每当我们用vue开发的时候 肯定会涉及到路由 那么大家有没有思考过 vue-router 到底是怎么实现的呢
首先 vue-router作为vue的一个插件 其次 里面有两个组件 router-view 和router-link 所以 思路就出来了
接下来 我们自己实现一个插件 先看下代码
let Vue
class VueRouter {
constructor(options){
this.$options = options
let initial = window.location.hash.slice(1) || "/"
Vue.util.defineReactive(this,"current",initial)
window.addEventListener('hashchange',()=>{
this.current = window.location.hash.slice(1)
})
}
}
VueRouter.install=function(vue){
Vue = vue
// 挂载router属性
// mixin是为了延迟 use的时候会先调用
Vue.mixin({
beforeCreate() {
if(this.$options.router){
Vue.prototype.$router = this.$options.router
console.log(vue,this.$options.router,99)
}
},
})
Vue.component("router-link",{
props:{
to:{
type:String,
required:true
}
},
render(h){
return h('a',{attrs:{href:"#"+this.to}},this.$slots.default)
}
})
Vue.component("router-view",{
render(h){
let component = null
let route = this.$router.$options.routes.find(route=>route.path===this.$router.current)
if(route){
component = route.component
}
return h(component)
}
})
}
export default VueRouter
vue.use的时候 会调用install方法的执行 然后用mixin 延迟执行在每个实例组件创建的时候 都挂载一下$router 不然的话 use执行的时候 还获取不到相关的options
第二点就是 创建响应式数据 Vue.util.defineReactive(this,"current",initial) 不然的话 数据改变 但是页面路径不会发生改变 因为数据不是响应式的数据
好了 动动你们的小手 自己自行尝试一下 具体实现 要看vue-router的源码 不过思路差不多 就是多了一些处理和模式的区分