VueRouter的实现原理
手写一个router注入
前言知识
1、VueRouter 其实是一个插件的形式注入到Vue中的【
Vue.use(VueRouter)
】
2、要知道VueRouter的底层在浏览器中使用的是hash
和histroy
两种模式,在node服务端使用的是abstract
- hash :直接就是使用
onhashchange
- histroy : 使用了H5 histroy API 中的
histroy.pushState(state,title,url)
、histroy.replaceState()
来触发popstate() //【将用户浏览的记录添加到路由的堆栈中,了解就好】
3、要知道Vue中的混入
mixin
,不管是插件还是组件,Vue通过混入的方式来进行注册
4、知道这些,就开始手写一个router的注入吧!!!
我们先来like like VueRouter在Vue中的注册
const router = new VueRouter({
routes:[
{
path:'/foo',component:()=>import('Foo')},
...
]
})
new Vue({
router,
render:h=>h(App)
}).$mount('#app)
1、创建一个Router类
// 创建一个index.js
const _Vue = null // 3.1保存Vue
export default class VueRouter{
// 1.初始化一个install方法,因为Vue在Vue.use需要执行install方法
static install(Vue){
//2.给当前对象上添加一个属性installed,用来判断VueRouter是否已经注册过,可以理解为让VueRouter只进行一次注册
//已经注册直接return
if(VueRouter.install.installed) return
//否则,注册
VueRouter.install.installed = true
// 3.后面需要用到Vue实例对象,所以现在全局进行保存
_Vue = Vue
// 4. 开始混入注册
_Vue.mixin({
// 4.1 注册需要在Vue实例创建时进行注册,所以在Vue的第一个生命周期钩子中调用
beforeCreate(){
// 4.3 这里需要先判断是否存在
if(this.$options.router){
// 4.2 将router挂载到Vue实例上,就像VueRouter中可以使用this.$router.push()这样
_Vue.prototype.$router = this.$options.router
}
}
})
}
}
到此注册阶段差不多了
2、在VueRouter类中创建构造函数
const _Vue = null
export default class VueRouter{
install(Vue){
...
}
// 5.创建构造函数
constructor(options){
// 5.1 此处的options相当于routes中的一个一个对象
this.options = options
// 5.2 初始化一个路由对象集合,处理路由和组件的对应关系
this.routeMap = {
}
// 5.3 初始化一个data,将data处理为响应式的
this.data = _Vue.