vue-vue的插件机制与install

114 阅读1分钟

核心要点

  • Vue的插件机制
  • Vue-Router插件在install期间到底干了什么
  • install在Vue中的内部实现

1、Vue的插件机制

  • 我们在使用Vue的时候,经常会使用并写一些自定义的插件,然后利用Vue.use引入;Vue.js 的插件应该暴露一个 install 方法。这个方法的第一个参数是 Vue 构造器,第二个参数是一个可选的选项对象

2、Vue-Router插件在install期间到底干了什么

(1)代码实例

  • 插件制作时会通常会加上 install 方法,我们以 Vue-Router 为例

    class Router {
       constructor(options) {
           ...
       }
    }
    
    Router.install = function(_Vue) {
    
       _Vue.mixin({
           beforeCreate() {
               if (this.$options.router) {
                   _Vue.prototype.$router = this.$options.router
               }
           }
       })
    
    }
    
    export default Router;
    
  • 然后我们在项目中使用 Vue-Router 插件

    // router/index.js
    
    import VueRouter form 'vue-router';
    import Vue from 'vue';
    
    Vue.use(VueRouter);
    
    const _router = [...]
    const Router = new VueRouter(_router);
    
    export default Router;
    
    
    // main.js
    
    import Vue from 'vue';
    import router from 'router';
    	
    new Vue({
        router,
    	 ...
    }).$mount('#app');
    
    

(2)根据上面的例子我们进行分析

  • Vue.use() 主要是调用插件内部的 install 方法,并将 Vue实例 作为参数传入;
  • 上面使用的是this.$options.router,options通常代表的是配置项,在main.js中我们把Router实例作为配置项传入到Vue实例中

(3)Vue-Router 挂载流程

  • 通过执行 Vue.use(),调用插件内部的 install 方法,并将 Vue实例 作为参数传入
  • install 方法中,通过 Vue.mixin 做了一个全局混入,为了在合适的时间点,获取到Vue根实例配置项中的router实例,执行挂载
  • 紧接着在 new Vue() 根实例创建的时候,注入 router实例,然后触发全局混入中的生命周期,这个时候根实例的配置项this.$options已经包含了router实例,最后完成挂载流程

3、install在Vue中的内部实现

  • 核心作用就是use的时候,判断插件类型,执行install或者插件本身

    export function initUse (Vue: GlobalAPI) {
        // 注册一个挂载在实例上的use方法
        Vue.use = function (plugin: Function | Object) {
            // 初始化当前插件的数组
            const installedPlugins = (this._installedPlugins || (this._installedPlugins = []))
            // 如果这个插件已经被注册过了,那就不作处理
            if (installedPlugins.indexOf(plugin) > -1) {
    
                return this
    
            }
    
            ...
            
            // 重点来了哦!!!
            if (typeof plugin.install === 'function') {
            // 当插件中install是一个函数的时候,调用install方法,指向插件,并把一众参数传入
                plugin.install.apply(plugin, args)
    
            } else if (typeof plugin === 'function') {
            // 当插件本身就是一个函数的时候,把它当做install方法,指向插件,并把一众参数传入
                plugin.apply(null, args)
    
            }
            
            // 将插件放入插件数组中
            installedPlugins.push(plugin)
    
            return this
        }
    }