序言
今天我们老大给我们讲了一下Vue.use的工作原理,一开始他以为我们都会,没想到一圈下来竟然都不尽如意,原来表面看起来很熟悉的东西,认真总结,却发现遗漏的东西很多,并不连通,今天我们就来整理一下Vue.use的工作原理吧。
基本使用
在探寻工作原理之前,我们先来看下官方是如何定义我们使用的
添加全局方法或者 property。如:vue-custom-element
Vue.myGlobalMethod=function(){//逻辑...}
添加全局资源:指令/过滤器/过渡等。如 vue-touch
Vue.directive('my-directive',{bind(el,binding,vnode,oldVnode){//逻辑...}...})
通过全局混入来添加一些组件选项。如 vue-router
Vue.mixin({created:function(){//逻辑...}...})
添加 Vue 实例方法,通过把它们添加到 Vue.prototype 上实现。
Vue.prototype.$myMethod=function(methodOptions){//逻辑...}
一个库,提供自己的 API,同时提供上面提到的一个或多个功能。如 vue-router
Vue中的插件
看完了使用方法,我们看见,我们把要注册的插件引用作为参数传入,就能实现注册,那么我们的插件是如何完成注册的呢。 在这之前,我们看一下符合注册规则的插件长啥样。
插件的本质是一个函数或者是对象
如果是对象的话,里面要有一个install方法,为什么要Install方法呢,耐心看到执行流程你就会明白。
一个插件的例子
//为对象时exportdefault{objectPlugin}functioninstall(Vue,option){console.log(vue);console.log(option);Vue.prototype.coolFish=coolFish}functioncoolFish(food){console.log(`coolFishlike${food}`)}//为function时functionfuncPlugin(a,b){console.log('Plugin2第一个参数:',a)console.log('Plugin2第二个参数:',b)}
我们通过分析上面代码,知道当插件为对象时, 有一个install 方法接受一个 Vue 实例和一个参数option,执行的操作为把当前的方法挂载到原型上面。当插件为function时,一切看起来很正常,我们接下来看一下Vue.use的源码,来理解一下为什么会这么做。
Vue.use源码分析
import{toArray}from'../util/index'exportfunctioninitUse(Vue:GlobalAPI){Vue.use=function(plugin:Function|Object){constinstalledPlugins=(this._installedPlugins||(this._installedPlugins=[]))if(installedPlugins.indexOf(plugin)>-1){returnthis}//additionalparametersconstargs=toArray(arguments,1)args.unshift(this)if(typeofplugin.install==='function'){plugin.install.apply(plugin,args)}elseif(typeofplugin==='function'){plugin.apply(null,args)}installedPlugins.push(plugin)returnthis}}
上面这段是Vue.use的源码片段,可以分为一下几个步骤:
创建一个插件数组,并且检测传入插件是否已经在此数组中,如果有的话,就不注册,直接返回,以免插件重复注册。
将 options 类数组对象转换为数组,再将 Vue 实例插入,做第一项。
判断当前插件是否有 install 方法,有的话将参数使用apply传入,这样我们前面定义的install 方法就取到了 Vue 实例,完成原型挂载。
如果插件本身为一个函数,那么直接把当前参数绑定上去。
最后把绑定完成的方法,加入到注册列表,防止重复注册。
总结:这样就解释了为啥当插件为对象时,需要 install 方法,这样才能把他绑定到原型上,完成动态注册。