本文是拉勾教育的课程笔记
VueRouter是个Class类,其中包含install方法
install方法(参数为Vue构造函数)中需要实现3个步骤
- 判断当前插件是否已经被安装
- 把Vue构造函数记录到全局变量
- 通过Vue.mixins把创建Vue实例时候传入的router对象注入到Vue实例上
- Vue.component注册router-link、router-view两个组件,这里再次复习了render函数
constructor构造函数
- 初始化options
- 遍历options.routes生成routeMap(path-component键值对)
- 注册事件监听(hashchange;popstate)
let Vue
export default class VueRouter {
static install (_Vue) {
// 判断插件是否已被安装
if (this.install.installed) {
return
}
this.install.installed = true
// 记录Vue构造函数方便后续使用
Vue = _Vue
const isDef = val => val !== undefined
// 使用Vue的全局混入将new Vue时候传入的router实例挂载到Vue实例上
Vue.mixin({
beforeCreate () {
// 判断是不是跟组件
if (isDef(this.$options.router)) {
// router实例挂载到Vue实例上
Vue.prototype.$router = this.$options.router
}
}
})
Vue.component('router-link', {
props: {
to: String
},
render (h) {
return h('a', {
attrs: {
href: this.to
},
on: {
click: this.handleClick
}
}, [this.$slots.default])
},
methods: {
handleClick (e) {
history.pushState({}, '', this.to)
this.$router.current = this.to
e.preventDefault()
}
}
})
Vue.component('router-view', {
render (h) {
console.log('this.$router.routerMap', this.$router.routerMap)
const component = this.$router.routerMap[this.$router.current]
return h(component)
}
})
}
// 构造函数
constructor (options) {
// 赋值geioptions
this.options = options
this.routerMap = {}
// 创建响应式对象
// 方法一
// this.data = Vue.observable({
// current: '/'
// });
// 方法二
// 其实方法一和方法二是一个道理,Vue.observable就是调用Vue.util.defineReactive
Vue.util.defineReactive(this, 'current', '/')
// 完成path-component键值对
this.options.routes.forEach(({ path, component }) => {
this.routerMap[path] = component
})
window.addEventListener('popstate', () => {
console.log(window.location.pathname)
this.current = window.location.pathname
})
}
}