Vue代码复用之混合(Mixin)

本文整理自GitChat陈陆杨的达人课《Vue2.0 渐进开发应用实践》

混合属性

混合属性是一直比组件更小颗粒度的复用方式,它以对象的形式存在,可以包含任意的组件选项(如 data、methods 等)。当组件使用混合对象的时候,将合并混合对象中的组件选项。

混合属性的使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// mixin.js
export default {
data () {
return {
fromMixin: true
}
},

created () {
console.log('created from mixin')
}
}

// MixinDemo.vue
import Mixin from './mixin.js'

export default {
mixins: [myMixin]
}

这样MixinDemo.vue就拥有了mixin.js中定义的datamethods选项。

混合属性作用域

在混合属性中也可以直接使用this,这会指向到使用该混合属性的组件实例上,例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// mixin.js
export default {
created () {
console.log(this.name)
}
}
// MixinDemo.vue
import Mixin from './mixin.js'

export default {
mixins: [myMixin],
data () {
return {
name: 'mixin demo'
}
}
}

混合属性created函数中输出的是组件MixinDemo.vue中的name值。

选项合并

如果mixins中的选项与组件选项定义了相同的属性的话,根据属性的不同,有两种处理方式:

  • 合并:生命周期钩子函数,两者的函数会合并成一个数组,依次调用,混合属性的钩子函数先于组件的同名钩子函数调用。watch也按此规则处理。
  • 覆盖:data computed methods components directives,则会被混合成一个对象,键名冲突时,取组件选项键值对
    Mixin 实例请参考这里

常见场景

混合属性通常可以用来实现很多非业务场景的能力,例如我们可以将 Vue 1 中的广播派发事件机制在混合属性中实现,这样如果有组件需要这样的通信机制,直接引入该混合属性即可。例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// emitter.js
const broadcast = function(eventName, params) {
// 遍历所有的子组件,若子组件存在对应事件的监听,则触发
this.$children.forEach(child => {
child._events[eventName] && child.$emit(eventName, params);
// 若子组件也包含子组件,则继续遍历
if (child.$children.length) {
broadcast.call(child, eventName, params);
}
});
};
export default {
methods: {
dispatch(eventName, params) {
// 获取元素父组件
let parent = this.$parent || this.$root;
while (parent) {
// 若父组件存在对应事件,则触发并结束向上派发
if (parent._events[eventName]) {
parent.$emit(eventName, params);
break;
} else {
// 若不存在则继续向上寻找
parent = parent.$parent;
}
}
},
broadcast(eventName, params) {
broadcast.call(this, eventName, params);
}
}
};

完整实例请单击这里