Vue.use是Vue註冊plugin的一種方法,那麼這個過程當中發生了什麼?經過源碼來看一下,vue註冊plugin的過程。vue
這裏咱們以vue-router爲例,順便看一下vue-router的實現原理。node
關於如何尋找源碼,經過查找響應npm包的package.json文件中的main屬性,這就是咱們引入npm包的入口文件的路徑。vue-router
function initUse (Vue) {
Vue.use = function (plugin) {
var installedPlugins = (this._installedPlugins || (this._installedPlugins = []));
if (installedPlugins.indexOf(plugin) > -1) {
return this
}
// additional parameters
var args = toArray(arguments, 1);
args.unshift(this);
if (typeof plugin.install === 'function') {
plugin.install.apply(plugin, args);
} else if (typeof plugin === 'function') {
plugin.apply(null, args);
}
installedPlugins.push(plugin);
return this
};
}
複製代碼
查看這部分源碼,咱們能夠發現vue首先判斷這個插件是否被註冊過,不容許重複註冊。 而且接收的plugin參數的限制是Function | Object兩種類型。 對於這兩種類型有不一樣的處理。npm
若是咱們傳入的plugin(Vue.use的第一個參數)的install是一個方法。也就是說若是咱們傳入一個對象,對象中包含install方法,那麼咱們就調用這個plugin的install方法並將整理好的數組當成參數傳入install方法中。 => plugin.install.apply(plugin, args) 若是咱們傳入的plugin就是一個函數,那麼咱們就直接調用這個函數並將整理好的數組當成參數傳入。 => plugin.apply(null, args) 以後給這個插件添加至已經添加過的插件數組中,標示已經註冊過 => installedPlugins.push(plugin) 最後返回Vue對象。json
首先咱們按照上面說的方法找到vue-router的源碼數組
import View from './components/view'
import Link from './components/link'
export let _Vue
// 這裏就是在Vue.use中會別執行的install方法
export function install (Vue) {
if (install.installed && _Vue === Vue) return
install.installed = true
_Vue = Vue
const isDef = v => v !== undefined
const registerInstance = (vm, callVal) => {
let i = vm.$options._parentVnode
if (isDef(i) && isDef(i = i.data) && isDef(i = i.registerRouteInstance)) {
i(vm, callVal)
}
}
// 對Vue實例混入beforeCreate鉤子操做(後續能夠繼續看一下mixin的源碼)
Vue.mixin({
beforeCreate () {
if (isDef(this.$options.router)) {
this._routerRoot = this
this._router = this.$options.router
this._router.init(this)
Vue.util.defineReactive(this, '_route', this._router.history.current)
} else {
this._routerRoot = (this.$parent && this.$parent._routerRoot) || this
}
registerInstance(this, this)
},
destroyed () {
registerInstance(this)
}
})
// 經過Vue.prototype定義$router、$route 屬性(方便全部組件能夠獲取這兩個屬性)
Object.defineProperty(Vue.prototype, '$router', {
get () { return this._routerRoot._router }
})
Object.defineProperty(Vue.prototype, '$route', {
get () { return this._routerRoot._route }
})
// Vue上註冊router-link和router-view兩個組件
Vue.component('RouterView', View)
Vue.component('RouterLink', Link)
const strats = Vue.config.optionMergeStrategies
// use the same hook merging strategy for route hooks
strats.beforeRouteEnter = strats.beforeRouteLeave = strats.beforeRouteUpdate = strats.created
}
複製代碼
Install解析 (對應目錄結構的install.js)bash
該方法內主要作了如下三件事:app