1、什么是Mixin混入:
混入(Mixin
)是 Vue.js
中用于复用部分组件逻辑的一种技术。通过混入,你可以将组件的方法,生命周期钩子,甚至 data 都进行复用。
混入的基本工作原理是把一个特定的对象“混入”到另外一个对象之中,如方法,组件选项等。它允许你写出可复用的代码并且可以插入到Vue实例中,或者本地组件中。
举个例子,如果你有一些组件,他们都需要在创建时(created钩子)请求数据,那么你就可以把这个请求的逻辑写进一个混入的对象中。然后在需要请求数据的组件中引入这个混入对象,这些组件就会拥有相同的创建逻辑。
同样的,如果你想让许多组件有相同的方法,也可以将它们写入混入对象,然后将这个混入对象引入至你的组件中。这样就可以减少重复代码,提高代码复用性。
在 Vue2
中,可以使用 Vue.mixin()
方法来全局注册混入,也可以在单个 Vue
组件中使用mixins
选项来使用混入。
要注意的是,混入对象的钩子将在组件自身钩子之前调用。而
在遇到同名选项时,比如 methods
、components
或者 props
,混入对象的选项会被合并到组件的选项中。对于同名的方法,混入的方法会在组件的方法之前调用。
2、使用场景:
当在多个组件中有相同的业务逻辑时,可以使用mixin,在mixin中定义这些公共的逻辑,然后在需要的组件中引入,在全局引入的时候可以用Vue.mixin,局部引入可以在组件的mixins选项中声明。
混入可以避免组件之间大量重复相同的方法或者逻辑代码,把这些公共的方法或者逻辑代码抽离出来,定义为一个混入对象,在不同的组件中调用,从而实现代码重用。
以下是一些可能会使用混入的场景:
- 数据格式化:通常我们可能需要在多个组件中实现对某一类型的数据进行格式化,可以通过mixin编写一个统一的数据格式化方法并混入各个组件中。
let formatMixin = {
methods: {
formatData(data) {
// 实现数据格式化逻辑
}
}
}
export default formatMixin;
然后在需要使用的组件中,使用import引入即可。
- 功能复用:例如我们在多个视图组件中都需要实现类似的滚动加载,可以通过mixin编写一段通用的滚动加载逻辑并混入。
let scrollMixin = {
directives: {
'scroll-more': {
bind: (el, binding) => {
let callback = binding.value;
el.addEventListener('scroll', () => {
if (el.scrollHeight - el.scrollTop - el.clientHeight < 10) {
callback();
}
})
}
}
}
}
export default scrollMixin;
- 对外提供插件或工具:例如我们要编写一套跨项目使用的输入验证工具,我们可以通过mixin封装我们的验证逻辑并对外发布,让其他项目在使用时可以以混入的方式获得输入验证的能力。
每个组件使用 mixin 时,mixins 选项接收一个混入对象的数组。
import MyPlugin from 'my-plugin'
export default {
mixins: [MyPlugin],
// ...
}
需要注意的是,当组件和混入对象含有同名选项时,这些选项将以适当的方式进行“合并”。像 data,methods,components,directives
等选项的合并,采取的策略是:同名钩子函数将合并为一个数组,因此都将被调用。另外,混入对象的钩子将在组件自身钩子之前调用。像 data
这样的对象选项,应当以组件的数据优先。
3、使用步骤:
以下是在 Vue2
中使用mixin
的主要步骤:
- 首先,我们需要创建一个
mixin
对象。mixin
对象可以包含任何组件选项。当组件使用了这个mixin
对象时,所有的mixin
对象选项将被“混入”到这个组件的选项中。
示例:
//创建一个mixin
var myMixin = {
data: function () {
return {
message: 'hello',
foo: 'abc'
}
},
methods: {
showMessage: function () {
alert(this.message);
}
}
}
- 接下来,我们可以在一个组件中使用这个
mixin
。用 Vue 的mixins
选项让组件使用这个mixin
。如此一来,组件就得到了mixin
中的数据和方法。
示例:
var Component = Vue.extend({
mixins: [myMixin]
})
这样,Component
实例就可以直接使用 myMixin
中定义的数据和方法了。
需要注意的是,当发生冲突时(即组件和混入对象含有同名选项),会有一些规则:
-
数据对象:在冲突的情况下,组件数据优先级高于
mixin
。 -
生命周期函数:不论是
Vue
的生命周期钩子还是自定义钩子,两者都会被调用。而且mixin
的钩子在组件自己的钩子之前调用。 -
选项合并:
Vue.js
使用自定义的合并策略来合并methods
,components
和directives
等。如果组件与混入对象有冲突,则组件选项优先级较高。
var mixin = {
created: function () {
console.log('混入对象的钩子被调用')
}
}
new Vue({
mixins: [mixin],
created: function () {
console.log('组件的钩子被调用')
}
})
// => "混入对象的钩子被调用"
// => "组件的钩子被调用"
4、与vuex的区别:
vuex是Vue的状态管理工具,它采用集中式存储管理应用的状态,适用于大型应用,mixin更多的是解决不同组件之间逻辑复用的问题,适用于任何类型的应用。
项目 | Vue2中的Mixin混入 | Vuex |
---|---|---|
定义 | Mixins在Vue.js中是一种代码复用技术. 允许用户在多个组件中复用JavaScript功能 | Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式,使用集中式存储来管理所有组件的状态 |
使用场景 | 对于那些多个组件间具有相同或类似功能的场景特别适合,避免代码冗余和重复。 比如全局的提醒/通知,共享一些工具函数等。 | 当你处理多个组件共享状态时,Vuex会更有益处. 如果几个视图需要处理同样的状态,那么你更应该使用Vuex了。 Vuex让我们可以在应用的所有组件中获取和设置应用状态的一个引用 |
组件访问 | 任何组件使用mixin后,mixin内容将融入到该组件本身,可以使用this来直接访问 | Vuex的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地更新 |
插件兼容 | 不是必要的,可以在任何Vue项目中使用mixin,无需像Vuex一样作为插件来使用 | Vuex是Vue的官方插件,需要在项目中单独通过Vue.use()方法来安装使用 |
开发团队 | 通常在一个团队中开发时,由于不同人的开发习惯和水平不同,频繁使用mixin可能会带来一些混乱问题,比如命名冲突,覆盖问题等 | Vuex的状态管理模式使得状态的变化更为可预测和理解,对于协同开发和维护大型项目特别有用 |
数据源 | mixin是分散的,每个组件都有可能有自己的mixin,无法做到像vuex一样集中管理 | Vuex所有的状态信息都是集中在一个对象中,易于管理和维护 |
5、与公共组件的区别:
mixin是一种抽象出通用逻辑代码的手段,对于某些类似的逻辑或者相同的逻辑,只编写一次,可以分发到各个组件中,可以减少代码冗余,公共组件则是一个具体的、可视的代码片段,可以直接使用。例如,你可能会拥有一页公共头部、页脚或者侧边栏。
Mixin混入 | 公共组件 | |
---|---|---|
定义 | Mixin在Vue2中是一种分发Vue组件中的可复用功能的非常灵活的方式。一个Mixin对象可以包含任意组件选项。当组件使用mixin对象时,所有mixin对象的选项将被混入该组件本身的选项。 | 公共组件是一种可在任何其他组件中复用的组件,它根据输入的属性和触发的事件有特定的功能。公共组件可以是任何的Vue component,只要它设置了正确的输入和输出。 |
用途 | Mixin混入用于封装一些通用的方法和数据,不涉及DOM操作,没有具体的模板渲染,更易于代码的组织和复用,有利于代码的维护。 | 公共组件被用于重复利用模板和一些对应的逻辑。一旦我们创建了公共组件,我们就可以在任何其他组件中复用它,只需将需要的数据传入即可。 |
引入 | Mixin扩展可以全局引入也可以局部引入,在全局引入的时候之后的所有组件中都可使用,局部引入则只有当前组件可使用。 | 公共组件经常在Vue的组件中通过import的方式引入,并在components选项内部局部注册后,才能在模板中使用。 |
注意项 | Mixin会和Component进行合并操作,也就是说如果Component本身存在于Mixin相同的选项或者函数的话,Component的内容会覆盖mixin的内容。如果函数同名,执行顺序为先混入的后执行。 | 公共组件需要设计得足够通用,并具有清晰的输入和输出接口,才能保证在各种场景下都能使用。需要注意的是,当公共组件的内部状态发生更改时,应该及时发出事件来通知父组件,以保持数据的一致性。 |