Vue混入(mixin)笔记

mixin是一种组件间的代码共享机制,允许你将代码封装为一个独立模块,将其用于在多个组件之间共享

mixin介绍

Vue中的mixin

先来看一下官方定义:

mixin(混入),提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。

本质其实就是一个js对象,它可以包含我们组件中任意功能选项,如datacomponentsmethodscreatedcomputed等等

我们只要将共用的功能以对象的方式传入 mixins选项中,当组件使用 mixins对象时所有mixins对象的选项都将被混入该组件本身的选项中来

Vue中我们可以局部混入全局混入

局部混入

定义一个mixin对象,有组件optionsdatamethods属性

1
2
3
4
5
6
7
8
9
10
var myMixin = {
created: function () {
this.hello()
},
methods: {
hello: function () {
console.log('hello from mixin!')
}
}
}

组件通过mixins属性调用mixin对象

1
2
3
Vue.component('componentA',{
mixins: [myMixin]
})

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

全局混入

通过Vue.mixin()进行全局的混入

1
2
3
4
5
Vue.mixin({
created: function () {
console.log("全局混入")
}
})

使用全局混入需要特别注意,因为它会影响到每一个组件实例(包括第三方组件)

PS:全局混入常用于插件的编写

注意事项

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

mixin使用场景

在日常的开发中,我们经常会遇到在不同的组件中经常会需要用到一些相同或者相似的代码,这些代码的功能相对独立。这时,可以通过Vuemixin功能将相同或者相似的代码提出来。

举个例子:定义一个modal弹窗组件,内部通过isShowing来控制显示

1
2
3
4
5
6
7
8
9
10
11
12
13
const Modal = {
template: '#modal',
data() {
return {
isShowing: false
}
},
methods: {
toggleShow() {
this.isShowing = !this.isShowing;
}
}
}

定义一个tooltip提示框,内部通过isShowing来控制显示

1
2
3
4
5
6
7
8
9
10
11
12
13
const Tooltip = {
template: '#tooltip',
data() {
return {
isShowing: false
}
},
methods: {
toggleShow() {
this.isShowing = !this.isShowing;
}
}
}

通过观察上面两个组件,发现两者的逻辑是相同,代码控制显示也是相同的,这时候mixin就派上用场了

首先抽出共同代码,编写一个mixin

1
2
3
4
5
6
7
8
9
10
11
12
const toggle = {
data() {
return {
isShowing: false
}
},
methods: {
toggleShow() {
this.isShowing = !this.isShowing;
}
}
}

两个组件在使用上,只需要引入mixin

1
2
3
4
5
6
7
8
9
const Modal = {
template: '#modal',
mixins: [toggle]
};

const Tooltip = {
template: '#tooltip',
mixins: [toggle]
}

通过上面小小的例子,让我们知道了Mixin对于封装一些可复用的功能如此有趣、方便、实用。

mixin存在的问题

mixin会引起的几类问题:

  • 命名冲突
  • 引起滚雪球般的复杂性
  • 隐式依赖

隐式依赖

我们知道,mixin模块内的代码和组件内的代码是等价的,如果你知道 mixin 中存在一个名为 hello 的方法,你完全和可以在组件中以 this.hello() 的形式无差别的对其进行调用。

假设某个同事在组件中偶遇了 hello 方法,想给它新增一个参数来实现更多的功能,这看上去不起眼的小事在实际操作起来却比登天还难。因为他根本不知道该方法是在哪个 mixin 模块中被定义的,他所知道的只有方法属于 this,于是他不得不翻看每一个 mixin 的定义

退一步说即使他在某个 mixin 中找到了该方法的定义,又会遇到另一个难题:不敢修改这个函数。虽然他可以知道有多少个组件文件引用了这个 mixin 模块,但是他不知道有多少处直接或者间接的调用了这个方法。也就是说这一次修改会造成的后果和带来的影响难以评估

所有这些问题的根源在于组件与 mixin 间,mixin 与 mixin 间的依赖是隐式的。也就是说当 A 模块依赖 B 函数时,这种关系既不是通过显示的声明(比如 import 语句或者依赖注入的方式)取得,也不是通过公共约定(例如 windows 对象上存在 getComputedStyle 方法)确定下来的。

这种关系也让 IDE 武功尽废,我发现解决这个问题的最后方式竟然是 Ctrl + C(复制),Ctrl + V(粘贴),Ctrl + Shift + F(全局查找),Ctrl + H(文本替换)。

参考


----------- 本文结束啦感谢您阅读 -----------

赞赏一杯咖啡

欢迎关注我的其它发布渠道