1
头图

前言

在前端开发中,作为开发者关于Vue框架的使用不必多说,Vue的框架也是目前最为好用的框架之一,虽然Vue3.0已经成为了主流版本(Vue2.0和Vue3.0还是有不少差别的),但丝毫不影响开发使用。本篇博文分享一个关于Vue相关的比较重要的知识点----混入(mixin),该内容在实际开发中比较常用,也比较重要,所以需要灵活运用,尤其是刚接触Vue不久的开发者甚为重要。

混入/混合的概念

Vue官方释义

Mixins are a flexible way to distribute reusable functionalities for Vue components. A mixin object can contain any component options. When a component uses a mixin, all options in the mixin will be “mixed” into the component’s own options.

混入/混合(Mixin)是一种为 Vue 组件分发可重用功能的灵活方式。mixin 对象可以包含任何组件选项。当组件使用mixin时,mixin中的所有选项都会“混合”到组件自己的选项中。

个人理解

混入/混合(Mixin)是Vue给开发者提供的一种混入实例的方法,定义一部分可复用的方法或者计算属性,包含任意组件选项,当组件使用混入对象的时候所有混入对象的选项将被混合进入该组件本身的选项,也就是通过创建混入对象之后,自定义的方法或变量都可以很容易挂载在Vue实例上,方便开发。

Vue混入(Mixin)

1、参数

{Object} mixin

2、用法

全局注册一个混入,影响注册之后所有创建的每个Vue实例。插件开发可以使用混入,向组件注入自定义的行为,但是不推荐在应用代码中使用。

Vue混入的方式

Vue.mixin提供两种混入方式:全局混入和局部混入。

1、全局混入

主要是通过Vue.mixin()进行全局混入,使用全局混入需要注意的是它会影响到每一个组件实例(包含第三方组件),一般情况下在写插件的时候会使用全局混入。混入对象可以成为一个可复用的功能,在其他的组件中引入已定义的混入对象,可实现同样的逻辑与功能,也就是可复用性。

示例:使用全局混入。
直接在项目的main.js文件中加入如下代码:

Vue.mixin({
data() {
 return {
   title: "Vue",
  }
},
created: function () {      
   console.log("全局")    
},
methods: {
  mixinMethods() {
     console.log("====>>>",this.title)
    }
  }
})

具体组件中引用的代码如下所示:

<template>
  <div>{{title}}</div>
</template>
<script>
export default {
  data() {
    return {}
  }
   mounted() {
     this.mixinMethod()   //输出结果: Vue
   }
}
</script>

2、局部混入

局部混入一般是在定义一个mixin对象,如组件options的data、methods等属性,如下所示:

var commonMixin = {
    created: function () {   
          this.fun() ;
    },
     methods: {   
      fun: function () {      
        console.log('This is Mixin');   
      }
    }
}

使用的时候,组件通过mixins属性调用mixin对象,如下所示:

Vue.component(
  'componentAAA',  {  mixins: [commonMixin] }
)

上面的组件在使用的时候,混合了mixin里面的方法,在自动执行create生命钩子的 时候,执行fun方法。

示例:局部混入使用
在组件componnets目录下创建一个mixins文件夹,且在该文件夹下创建一个mixins.js文件,代码如下所示:

const mixins = {
data() {
return {
title: "Vue"
}
},
methods: {
mixinMethods() {
console.log("====>>>",this.title)
}
}
}
export default mixins;

在具体需要的界面引用的代码如下所示:

<template>
<div>{{title}}</div>
</template>
<script>
import mixins from '../mixins/mixins'
export default {
mixins: [mixins],
data() {
return {}
}
mounted() {
this.mixinMethods() ;// 输出结果:Vue
}
}
</script>

3、一般方法合并的操作

如果混入值是对象的选项,如methods、components等,在进行递归合并操作时,把被混合为同一个对象,如果两个对象的键名因为一样而冲突的时候,将使用适当的策略合并操作,如数据对象进行递归合并,在发生冲突时组件的数据优先,会取组件对象中的键值对,而混入mixin的对象键值对会被忽略。具体示例如下所示:

<body>
<div id="app"></div>
</body>
<script src="./vue.js"></script>
<script>
var commonMixin = {
methods: {
mixinA: function() {
console.log('mixinA')
},
mixinB: function () {
console.log('mixinB')
}
}
}
new Vue({
el: '#app',
mixins: [ commonMixin ], 
methods: {
mixinMethods: function () {
console.log('mixinMethods')
}
},
mounted() {
this.mixinA()  //输出结果为:mixinMethods
this.mixinB() //输出结果为:mixinB
}
})
</script>

4、混入和组件钩子函数执行顺序

若组件存在于mixin对象相同选项为生命周期钩子函数的时候,会将同名的钩子函数合并到一个数组中,这样所有的钩子函数都会被调用,但是会按照先执行mixin里面的钩子函数,再执行组件的钩子函数,具体示例如下所示:

混入的文件mixins.js的代码

const mixins = {
data() {
return{
title1: '混入内容1',
title2: '混入内容2'
}
},
created() {
console.log(this.title3)
} 
}
export default mixins;
...

具体组件的代码:

<template>
<div class="header"></div>
</template>
<script>
import mixins from './mixins/mixins'
export default {
mixins: [mixins],
name: 'Header',
data(){
return{
title1: '组件内容1',
title3: '组件内容2'
}
},
created() {
console.log(this.title2);
console.log(this.title1);
  // 输出结果顺序为:我是组件内容2  我是混入内容2 我是组件内容1
},
}
</script>

5、自定义选项合并

在进行合并自定义选项的时候,会使用覆盖现有值的默认策略,若要使用自定义逻辑合并自定义选项,则需要把函数附加到Vue.config.optionMergeStrategies。示例如下所示:

Vue.config.optionMergeStrategies.myOption = function (toVal, fromVal) {
// return mergedVal
}

相对于大多数基于对象的选项,可以使用相同的策略methods。示例如下所示:

var strategies = Vue.config.optionMergeStrategies;
strategies.myOption = strategies.methods;

6、注意

如果组件存在与mixin对象相同选项的时候,在进行递归合并操作时,组件的选项会覆盖mixin的选项。但如果相同选项为生命周期钩子的时候,会合并成一个数组,会按照先执行mixin的钩子函数,再执行组件的钩子函数。

image.png

适用场景

在平时的日常开发过程中,经常会遇到在不同的组件中需要用到一些相同或者相似的功能代码块,而该部分的代码的能相对独立,这就可以通过使用Vue的混入mixin功能将相同或者相似的功能代码块提取出来使用。

还有就是针对一些基本功能相同的,但又存在比较大差异性的组件之间,也可以使用Vue中的Mixin来实现。因为Mixin对编写函数式风格的代码很有用,原因是函数式编程就是通过减少移动的部分让代码更好阅读,而且Mixin允许封装一个在应用的其他组件中都可使用的函数。

混入的优缺点

mixin的特点,既有优点也有缺点,所以要根据实际情况来选择使用。具体如下所示:

优点

可复用性强,方便提高组件代码复用,不用传递状态,可以修改一个地方引起全局都被修改的效果。

缺点

  1. 变量名不明确。使用mixin的时候,在查找变量和方法名的时候,需要逐层查找,全局搜索,不便于阅读查找和维护。所以需要在使用的时候统一放到一个位置,方便查找和维护;
  2. 如果是多个mixin的生命周期钩子函数融合到一处运行,且有同名的属性,那么同名的方法无法融合导致被覆盖或者冲突,再遇到组件中定义的属性,方法和mixin中的同名属性,那么组件的属性会覆盖所有的mixin中的属性;
  3. mixin和组件直接会出现多对多的关系,复杂度自然而然就变高了,这就是说一旦滥用,遇到问题就很难追溯代码和排查问题,代码极难维护;
  4. 全局混入,如果接手项目不熟的新人,会造成找不到属性和方法,不便于新手维护代码。但是如果业务逻辑需求明确,功能单一,后期无需修改,可以直接使用mixin来实现。

拓展:mixin混入和Vuex的区别

  •   Vuex是状态共享管理,Vuex中的所有变量和方法都是可以读取和更改并且相互影响;
  •   mixin可以定义公用的变量或方法,但是mixin中的数据是独立不共享的,即每个组件中的mixin实例都不一样,是单独存在的个体,不存在相互影响;
  •   如果mixin混入对象值是函数,同名函数选项将会进行递归合并为一个数组,且两个函数都会执行,只是先执行mixin中的同名函数后执行组件的同名函数;
  •   mixin混入对象值为对象,同名对象将会进行替换处理,优先执行组件内的同名对象,会把组件内的同名对象覆盖mixin混入对象的同名对象。

最后

mixin在Vue中的复用思想,是精简代码的一种方式,可以根据实际业务场景选择使用是全局混入还是局部混入,但是不能滥用,尤其是谨慎使用全局混入,因为会引起牵一发而动全身的影响。同时,混入是Vue开发使用和求职面试比较重要的知识点,需要完全掌握它的内涵,重要性不言而喻,直接掌握住即可。

本文参与了「SegmentFault 思否写作挑战赛」,欢迎正在阅读的你也加入。


三掌柜
20.1k 声望6.6k 粉丝

一分耕耘,不一定有一分收获,但十分耕耘,一定会有一分收获!