前言
最近在看vue-router和vuex的源码,都会有自己的install方法,然后通过mixin绑定到生命周期里
vue.use
vue.use兼容带install和不带install,这两种注册的方式都可以,只是install会更容易扩展
export function initUse (Vue: GlobalAPI) {
Vue.use = function (plugin: Function | Object) {
<!-- 已经use的插件数组 -->
const installedPlugins = (this._installedPlugins || (this._installedPlugins = []))
if (installedPlugins.indexOf(plugin) > -1) {
return this
}
// additional parameters
<!-- 把传入的参数整理成数组 -->
const args = toArray(arguments, 1)
<!-- 默认第一个参数是vue对象 -->
args.unshift(this)
<!-- 判断带不带install方法 -->
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-router
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)
}
}
<!-- 通过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)
}
})
<!-- 所有实例中 this.$router 等同于访问 this._routerRoot._router -->
Object.defineProperty(Vue.prototype, '$router', {
get () { return this._routerRoot._router }
})
<!-- 所有实例中 this.$route 等同于访问 this._routerRoot._route -->
Object.defineProperty(Vue.prototype, '$route', {
get () { return this._routerRoot._route }
})
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
}
总结
要写一个vue的插件,可以是带install或不带,然后在里面通过mixin,绑定prototype,调用component等方法去注册到vue实例上去
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。