Vue-Router
是Vue.js
官方的路由管理器, 开发者可以自由选择是否使用Vue-Router
作为路由管理器, 因为它是作为Vue插件的形式被安装到Vue中的.
如何安装一个Vue插件
如果插件是一个对象, 必须提供
install
方法. 如果插件是一个函数, 它会被作为install方法. install方法调用时, 会将Vue作为参数传入. 该方法需要在调用new Vue()
之前被调用
当
install
方法被同一个插件多次调用, 插件将只会被安装一次
以上是官方文档的描述, 我们还是看代码吧
// 该方法会在initGlobalAPI初始化全局api的时候被执行
export function initUse (Vue: GlobalAPI) {
// 在Vue对象上添加use方法, 方法的参数可以是方法或者对象
Vue.use = function (plugin: Function | Object) {
// 获取当前实例已经安装过插件列表
const installedPlugins = (this._installedPlugins || (this._installedPlugins = []))
// 判断是该插件是否已经被安装过
// 也就是文档描述的, 当同一个插件多次调用, 插件将只会被安装一次
if (installedPlugins.indexOf(plugin) > -1) {
return this
}
// 额外的参数
const args = toArray(arguments, 1)
// 把当前实例插入到参数数组的首位
args.unshift(this)
if (typeof plugin.install === 'function') { // 这里判断plugin是否提供了install方法
// 调用plugin.install, 并传入额外的参数
plugin.install.apply(plugin, args)
} else if (typeof plugin === 'function') { // 否则, 如果plugin是一个函数, 它会被作为install方法
// 把plugin作为install调用, 并传入额外的参数
plugin.apply(null, args)
}
// 把当前插件添加到已安装插件列表中
installedPlugins.push(plugin)
return this
}
}
复制代码
在代码中能更加清晰地了解到官方文档所描述的内容
Vue-Router的install
如果在一个模块化工程使用Vue-Router, 必须通过Vue.use()
明确地安装路由功能
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
复制代码
而在VueRouter被定义的时候, 已经定义了VueRouter.install
供Vue.use(VueRouter)
执行其install
方法
既然都定义了VueRouter.install方法, 那就顺便看一下install过程VueRouter都干了什么吧
// 这个方法的第一个参数是Vue构造函数, 第二个参数是一个可选对象
export function install (Vue) {
// 确认install只会调用一次
if (install.installed && _Vue === Vue) return
// 定义该插件已经被安装
install.installed = true
// 把Vue赋值给全局变量
_Vue = Vue
// 判断变量v是否不为undefined
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 注入组件
Vue.mixin({
beforeCreate () {
// 判断组件是否存在router对象, 该对象只在根组件上有
if (isDef(this.$options.router)) {
// 根路由设置为自己
this._routerRoot = this
this._router = this.$options.router
// 调用VueRouter实例的init()方法, 初始化路由
this._router.init(this)
// 为_route属性实现双向绑定
Vue.util.defineReactive(this, '_route', this._router.history.current)
} else {
// 用于router-view层级判断
this._routerRoot = (this.$parent && this.$parent._routerRoot) || this
}
registerInstance(this, this)
},
destroyed () {
registerInstance(this)
}
})
// 定义Vue.$router的返回值
Object.defineProperty(Vue.prototype, '$router', {
get () { return this._routerRoot._router }
})
// 定义Vue.$route的返回值
Object.defineProperty(Vue.prototype, '$route', {
get () { return this._routerRoot._route }
})
// 全局注册组件router-view和router-link
Vue.component('RouterView', View)
Vue.component('RouterLink', Link)
// 获取自定义选择合并策略
const strats = Vue.config.optionMergeStrategies
// beforeRouteEnter, beforeRouteLeave, beforeRouteUpdate 与 created使用相同的合并策略
strats.beforeRouteEnter = strats.beforeRouteLeave = strats.beforeRouteUpdate = strats.created
}
复制代码
以上就是Vue.use(VueRouter)的过程, 这也是为什么Vue-Router能被Vue使用的实现, 了解这些等于知道如何开始自己开发Vue插件了