Vue2插件的基本原理——vue2源码探究(2)

707 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 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('组件钩子被调用')
    }
  })
  
  // => "混入对象的钩子被调用"
  // => "组件钩子被调用"
  • 值为对象的选项,例如 methodscomponents 和 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) {
    // 逻辑...
}