vue - router 工作流程
hash-history
hash
history
- history即正常的路径
- location.pathname
- 可以onpopstate监听history变化
Vue-router
vue-router是一个第三方插件
实现
- vue.use()去使用一个插件,会执行其中 install
- vue.mixin往vue的全局中混入自定义的操作
- 通过this.$options拿到new vue的参数
简单的自定义插件vue使用
自定义插件myRouter.js
class VueRouter {
constructor(options){
}
}
VueRouter.install = function(Vue){
console.log("11111")
}
export default VueRouter;
import Router from "./myRouter";
Vue.use(Router);
会调用install方法,打印11111
vue-router 改写引用如下文件
class HistoryRoute {
constructor(){
this.current = null;
}
}
class VueRouter {
constructor(options){
this.history = new HistoryRoute()
this.mode = options.mode || "hash"
this.routes = options.routes || []
this.routesMap = this.createMap(this.routes)
this.init()
}
init(){
if(this.mode == "hash"){
// 路径没有#自动加上#
location.hash ? "" : location.hash = "/";
window.addEventListener( "load",()=>{
this.history.current = location.hash.slice(1); // 路径去掉#
})
window.addEventListener( "hashchange",()=>{
this.history.current = location.hash.slice(1);
})
}else{
location.pathname ? "" : location.pathname + "/";
window.addEventListener( "load",()=>{
this.history.current = location.pathname;
})
window.addEventListener( "popstate",()=>{
this.history.current = location.pathname;
})
}
}
createMap(routes){
return routes.reduce((memo,current)=>{
memo[current.path] = current.component
return memo;
})
}
}
VueRouter.install = function(Vue){
Vue.mixin({
beforeCreate() {
if(this.$options&&this.$options.router){
this._root = this
this._router = this.$options.router
Vue.util.defineReactive(this,'current',this._router.history)
}else {
this._root = this.$parent._root
}
// 设置一个读引用
Object.defineProperty(this,"$router",{
get(){
return this._root._router;
}
})
Object.defineProperty(this,"$route",{
get(){
return this._root._router.history.current;
}
})
},
});
Vue.component("router-view",{
render(h){
let current = this._self._root._router.history.current;
let routeMap = this._self._root._router.routesMap;
return h(routeMap[current])
}
})
vue.component(("router-view",引入自定义固定组件)//这里是没有问题的,但是写成上面根据路由自动切换显示有问题,可能是render里方法有问题,如果有知道答案的望告知
}
export default VueRouter;