Vue提供了全局的use方法去安装插件,使用use后会自动执行插件里的intall方法来安装:
/* @flow */
import { toArray } from '../util/index'
export function initUse (Vue: GlobalAPI) {
Vue.use = function (plugin: Function | Object) {
const installedPlugins = (this._installedPlugins || (this._installedPlugins = []))//保存Vue上已经有的插件
if (installedPlugins.indexOf(plugin) > -1) {
return this
}
// additional parameters
const args = toArray(arguments, 1)
args.unshift(this)//让每个插件的第一个参数都能拿到Vue
if (typeof plugin.install === 'function') {
plugin.install.apply(plugin, args)
} else if (typeof plugin === 'function') {
plugin.apply(null, args)
}
installedPlugins.push(plugin)
return this
}
}
这就是use的所有源码,很简单,先保存一份Vue已有的插件,然后看下新安装的插件是否存在,存在则退出,否则判断插件的install方法是否是函数或者是本身是函数,是则调用,然后返回Vue.
PS: 并且每个插件的install方法的第一个参数都能拿到vue
再看vue-router的install定义:
import View from './components/view'
import Link from './components/link'
export let _Vue
export function install (Vue) {
if (install.installed && _Vue === Vue) return
install.installed = true//vue-router只安装一次
_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.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)//将_route变为响应式的
} else {
this._routerRoot = (this.$parent && this.$parent._routerRoot) || this
}
registerInstance(this, this)
},
destroyed () {
registerInstance(this)
}
})
Object.defineProperty(Vue.prototype, '$router', {//这样每个vue实例都能访问了
get () { return this._routerRoot._router }
})
Object.defineProperty(Vue.prototype, '$route', {
get () { return this._routerRoot._route }
})
Vue.component('RouterView', View)//定义了<router-view>组件
Vue.component('RouterLink', Link)//定义了<router-link>组件
const strats = Vue.config.optionMergeStrategies
// use the same hook merging strategy for route hooks
strats.beforeRouteEnter = strats.beforeRouteLeave = strats.beforeRouteUpdate = strats.created//对3个钩子都采用created的策略
}
可以看到这个install做了几件事:
- 将Vue保存给_Vue.免得每次都要import
- 通过Vue.mixin给每个组件入住beforeCreate和destroyed两个构造函数
- 通过Object.defineProperty师德我们能通过Vue.router访问route和router。
- 注册了<router-view>和<router-link>2个组件使得我们全局可以使用。
总结:
1. Vue提供了全局的use方法去安装插件,使用use后会自动执行插件里的intall方法来安装,并且每个插件的install方法的第一个参数都能拿到vue
2. install方法将Vue保存给_Vue.免得每次都要import
3. install方法通过Vue.mixin给每个组件入住beforeCreate和destroyed两个钩子函数
4. install方法通过Object.defineProperty使得我们能通过Vue.$route和Vue.$router访问route和router。
5. install方法注册了<router-view>和<router-link>2个组件使得我们全局可以使用。
网友评论