携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第12天,点击查看活动详情
插件是什么
Vue的插件实际上是对Vue全局进行处理的工具,具体使用方式为:
Vue.use(Plugin)
它可以在生命周期钩子中运行代码,为每个实例绑定公共的数据或方法,甚至是可以引用自定义组件省去在每个Vue文件中都要重复写相同的components的繁琐步骤。
mixinAPI
插件本质上是使用了Vue全局的mixinAPI,不过,与其直接使用mixinAPI,更推荐的是将其包装在插件中,因为插件会自动删除,当你调用多次同一个插件时,它会自动删除以防止反复应用,而mixin则不会。
minix这个单词的意思是“混入”,意味着可以将代码混入到各个实例中,也就是说可以复用一段代码,一个mixin的最简单例子:
Vue.mixin({
created () {
console.log("Hello Vue!");
}
})
这段代码即为在实例的created钩子中,控制台里打印Hello Vue,如果将其写在main.js中,则每一个实例在初始化的时候,控制台中都会打印Hello Vue。
此外,mixin在混入时会与当前实例中相同的属性会以适当的方式进行合并:
- 数据对象在内部会进行递归合并,并在发生冲突时以组件数据优先
var mixin = {
data: function () {
return {
message: 'hello',
foo: 'abc'
}
}
}
new Vue({
mixins: [mixin],
data: function () {
return {
message: 'goodbye',
bar: 'def'
}
},
created: function () {
console.log(this.$data)
// => { message: "goodbye", foo: "abc", bar: "def" }
}
})
- 同名钩子函数将合并为一个数组,因此都将被调用。另外,混入对象的钩子将在组件自身钩子之前调用。
var mixin = {
created: function () {
console.log('混入对象的钩子被调用')
}
}
new Vue({
mixins: [mixin],
created: function () {
console.log('组件钩子被调用')
}
})
// => "混入对象的钩子被调用"
// => "组件钩子被调用"
- 值为对象的选项,例如
methods、components和directives,将被合并为同一个对象。两个对象键名冲突时,取组件对象的键值对。
var mixin = {
methods: {
foo: function () {
console.log('foo')
},
conflicting: function () {
console.log('from mixin')
}
}
}
var vm = new Vue({
mixins: [mixin],
methods: {
bar: function () {
console.log('bar')
},
conflicting: function () {
console.log('from self')
}
}
})
vm.foo() // => "foo"
vm.bar() // => "bar"
vm.conflicting() // => "from self"
包装为插件
上文提到过,更好的处理方式是将mixin包装在插件中,一个插件可以是直接的一个方法:
Vue.use((Vue,option) => {
Vue.mixin({
data() {
return {
message:"welcome Vue"
}
},
created() {
console.log(this.message)
}
})
})
也可以传递一个对象,在传入install方法在插件注册时候进行执行:
Vue.use({
install: (Vue, option) => {
Vue.mixin({
data() {
return {
message: "welcome Vue"
}
},
created() {
console.log(this.message)
}
})
},
})
插件的其他操作
实际上,除了mixin之外,插件中还可以进行以下操作:
- 添加全局方法或property
Vue.myGlobalMethod = function () {
// 逻辑...
}
- 添加全局资源
Vue.directive('my-directive', {
bind (el, binding, vnode, oldVnode) {
// 逻辑...
}
...
})
- 添加实例方法
Vue.prototype.$myMethod = function (methodOptions) {
// 逻辑...
}