您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

Vue 混入 Mixins

本节介绍混入 (mixin) 的使用。什么是 mixin,如何定义 mixin,mixin 重名的合并策略,全局 mixin 的使用。其中,了解和掌握 mixin 重名的合并策略非常重要,合并问题会在 mixin 的使用中经常出现。在学完本小节之后,同学们可以尝试总结出的合并的规则策略,这有助于加深印象,在日后的使用中也能得心应手。

混入 (mixin) 提供了一种非常灵活的方式,来分发 Vue 组件中的可复用。混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被 “混合” 进入该组件本身的选项。 – 官方定义

我们在日常开发中经常遇到多个或者模块有相同逻辑的情况,同学们在遇到此类情况的时候肯定会想:如果这段能够复用就好了!。那什么可以帮助我们实现复用呢?答案就是:Mixin! Mixin 帮助我们抽离公共逻辑。混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被 “混合” 进入该组件本身的选项。

接下来我一起看看如何定义和使用 mixin。

对于 mixin 的使用可以分为两部分:

mixin 本质上就是 Object 对象,它和 vue 实例上的一致,包含 data、methods、computed、watch、生命周期等等:

var myMixin = {
  data(){
    return {
      //...
    }
  },
  created() {
     //...
  },
  methods: {
    //...
  },
  computed() {
    // ...
  }
}

想要混入定义好的 mixin,只需要通过组件的 mixins 传入想要混入的 mixin 数组即可:

var vm = new Vue({
  el: '#app',
  mixins:[myMixin]
})

解释:
上述中,我们定义了 Vue 实例,并在实例上混入 myMixin。

接下来我们看简单的示例:

@H__183@<!DOCTYPE html>
<html lang="en">
<head>
  < charset="UTF-8">
  < name="viewport" content="width=device-width, initial-scale=1.0">
  < http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div id="app">
    我是:{{name}}, 年龄:{{year}}
  </div>
</body>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script type="text/javascript">
  // 定义 mixin
  var myMixin = {
    data(){
      return {
        name: '句号'
      }
    },
    created: function () {
      this.mixinFun()
    },
    methods: {
      mixinFun: function () {
        console.log('mixin function')
      }
    }
  };
  var vm = new Vue({
    el: '#app',
    // 使用mixin
    mixins:[myMixin],
    data() {
    	return {
        year: '18'
      }
    }
  })
</script>
</html>

解释:
JS 第 3-17 行,定义了混入对象 myMixin,并定义了数据 data、 created、 mixinFun。
JS 第 20 行,通过组件实例上的 mixins 引入 myMixin。

运行程序可以看到,在 myMixin 中定义的数据 name 渲染到上。同时打开控制台可以看到 ‘mixin function’ 被打印出来,说明 created 被执行。

我们在定义 mixin 时会出现名重复的情况,例如:

var myMixin = {
  data() {
    return {
      name: 'Imooc'
    }
  },
  create() {
    console.log('Imooc')
  }
}

var vm = new Vue({
  data() {
    return {
      name: '句号'
    }
  },
  create() {
    console.log('句号')
  }
})

当组件和混入对象含有同名选项时,这些选项将以恰当的方式进行 “合并”。这些重复项的合并有固定的规则,接下来我们从三个方面来详细讲解选项合并的规则。

数据对象在内部会进行递归合并,并在发生冲突时以组件数据优先。详细的合并规则如下:

@H__183@<!DOCTYPE html>
<html lang="en">
<head>
  < charset="UTF-8">
  < name="viewport" content="width=device-width, initial-scale=1.0">
  < http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div id="app"></div>
</body>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script type="text/javascript">
  var myMixin = {
    data(){
      return {
        isOpen: false,
        date: '2020-02-02',
        desc: {
          title: 'Mixins 基础教程',
          desc: '本教程将讲解如何使用 mixins',
          author: {
            name: '网',
            location: '北京'
          }
        }
      }
    }
  };
  var vm = new Vue({
    el: '#app',
    mixins:[myMixin],
    data() {
    	return {
        isOpen: true,
        date: new Date().toLocaleString(),
        desc: {
          author: {
            name: 'Imooc',
            age: '20'
          }
        }
      }
    },
    created() {
      console.log(this.data)
    }
  })
</script>
</html>

解释:
JS 第 3-15 行,定义了混入对象 myMixin,并定义了数据 data。
JS 第 18 行,通过组件实例上的 mixins 引入 myMixin。
JS 第 19-30 行,定义了组件实例上的数据 data。
根据之前我们学习的合并规则,得到的最终数据 data 格式如下:

data() {
  return {
    isOpen: true,
    date: new Date().toLocaleString(),
    desc: {
      author: {
        name: 'Imooc',
        age: '20',
        location: '北京'
      }
    }
  }
}

同名将合并为数组,因此都将被。另外,混入对象的钩子将在组件自身钩子之前。也就是说,如果我们在 mixin 和组件中都定义了 created,那么 mixin 和 组件中的都会被执行。需要注意的是:mixin 中的将在组件的之前执行。
具体示例:

@H__183@<!DOCTYPE html>
<html lang="en">
<head>
  < charset="UTF-8">
  < name="viewport" content="width=device-width, initial-scale=1.0">
  < http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div id="app">
    mixin 示例
  </div>
</body>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script type="text/javascript">
  var myMixin = {
    created() {
      alert('mixin created 先执行')
    }
  };
  var vm = new Vue({
    el: '#app',
    mixins:[myMixin],
    created() {
      alert('组件 created ')
    }
  })
</script>
</html>

解释:
JS 第 3-7 行,定义了混入对象 myMixin,并定义了 created。
JS 第 10 行,混入定义的 myMixin。
JS 第 11-13 行,在组件内部定义了 created。
所以,最终的运行结果是:
mixin created 执行
组件 created 执行

值为对象的选项,例如 methods、components 和 directives,将被合并为同对象。两个对象键名冲突时,取组件对象的键值对。

示例:

@H__183@<!DOCTYPE html>
<html lang="en">
<head>
  < charset="UTF-8">
  < name="viewport" content="width=device-width, initial-scale=1.0">
  < http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div id="app">
    mixin 示例
  </div>
</body>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script type="text/javascript">
  var myMixin = {
    methods: {
      sayName() {
        console.log('我是网')
      },
      sayHello() {
        console.log('hello 大家好')
      }
    }
  };
  var vm = new Vue({
    el: '#app',
    mixins:[myMixin],
    methods: {
      sayName() {
        console.log('我是句号')
      },
      sayYear() {
        console.log('我的年龄是:18')
      }
    }
  })
  vm.sayName() // ---> 我是句号
  vm.sayHello() // ---> hello 大家好
  vm.sayYear() // ---> 我的年龄是:18
</script>
</html>

解释:
JS 第 3-12 行,定义了混入对象 myMixin,并定义了两个。
JS 第 15 行,混入定义的 myMixin。
JS 第 16-23 行,在组件内部定义了两个。
由于值为对象的选项合并取组件对象的键值对。所以,最终的 methods 对象是:

methods: {
  sayName() {
    console.log('我是句号')
  },
  sayYear() {
    console.log('我的年龄是:18')
  },
  sayHello() {
    console.log('hello 大家好')
  }
}

混入也可以进行全局。使用时需要格外小心!一旦使用全局混入,它将影响每之后创建的 Vue 实例。使用恰当时,这可以用来为选项注入处理逻辑。通过 Vue.mixin ({…}) 可以全局混入:

Vue.mixin({
  data: {
    name: "Imooc"
  }
})

具体示例:

@H__183@<!DOCTYPE html>
<html lang="en">
<head>
  < charset="UTF-8">
  < name="viewport" content="width=device-width, initial-scale=1.0">
  < http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div id="app">
    mixin 全局混入 示例
  </div>
</body>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script type="text/javascript">
  Vue.mixin({
    created() {
      console.log('全局mixin created')
    },
    methods: {
      sayHello() {
        console.log('hello 大家好')
      }
    }
  })

  var vm = new Vue({
    el: '#app'
  })
  vm.sayHello()
</script>
</html>

解释:
JS 第 3-12 行,定义了全局混入对象,并定义了 created 和 sayHello 。
JS 第 14-16 行,创建了 Vue 实例。

因为全局混入会在之后创建的每 Vue 实例上混入,所以,控制台会以下数据:
全局 mixin created
hello 大家好

本节,我们带大家学习了混入 mixin 在 vue 项目中的运用。主要知识点有以下几点:


联系我
置顶