vue-router
###################
npm install vue-router
<router-link to="/user" tag="button" active-class="active" exact>Go to User Page</router-link>
这个例子中,当用户点击按钮时,会跳转到 /user
路由,并且按钮会添加 active
类名。另外,由于开启了精确匹配模式,只有当路径与目标路由完全匹配时才会添加 active
类名。
Vue.use()方法的源代码如下:
function install(Vue) { // 避免重复安装插件 if (install.installed && _Vue === Vue) return install.installed = true _Vue = Vue // 执行插件的安装方法 const isDef = val => val !== 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() { // 如果有router选项,则把router挂在到vue实例上 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) }, }) // 注册router-link和router-view全局组件 _Vue.component('RouterView', View) _Vue.component('RouterLink', Link) // 在Vue原型上定义$router和$route属性 Object.defineProperty(Vue.prototype, '$router', { get() { return this._routerRoot._router } }) Object.defineProperty(Vue.prototype, '$route', { get() { return this._routerRoot._route } }) // 注册钩子函数,用于处理VueRouter的生命周期 Vue.mixin({ beforeRouteEnter(to, from, next) { next(vm => { if (!vm._isMounted) { // 如果Vue组件没有挂载,则在挂载时再执行beforeRouteEnter函数 vm.$nextTick(() => { next(vm) }) } }) }, beforeRouteUpdate(to, from, next) { const { matched } = this.$route const prevMatched = from.matched let diffed = false const activated = matched.filter((c, i) => { return diffed || (diffed = (prevMatched[i] !== c)) }) if (!activated.length) { this.$nextTick(() => { next() }) } else { const queue = activated.map(c => { return new Promise((resolve, reject) => { if (c.beforeRouteEnter) { c.beforeRouteEnter(to, from, () => { resolve() }) } else { resolve() } }) }) Promise.all(queue).then(() => { next() }).catch(() => { next(false) }) } }, beforeRouteLeave(to, from, next) { const matched = this.$route.matched const component = matched[matched.length - 1] if (!component || !component.beforeRouteLeave) { next() } else { component.beforeRouteLeave(to, from, () => { next() }) } } }) } export default { install, }
##########################
igoodful@qq.com