自己简单写一个 vue-router

vue - router 工作流程

某教案截图

hash-history

hash

  • 号后的就是hash的内容

  • 可以通过location.hash拿到
  • 可以通过onhashchange监听hash内容的改变

history

  • history即正常的路径
  • location.pathname
  • 可以onpopstate监听history变化

Vue-router

vue-router是一个第三方插件

实现
  • vue.use()去使用一个插件,会执行其中 install
  • vue.minxin往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.components
            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;
发布了158 篇原创文章 · 获赞 11 · 访问量 1万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 技术工厂 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览