Vue-Router 实现原理

Vue-Router 实现原理

参考:https://www.jianshu.com/p/d59971198082

需要明白的是,router-linkrouter-view 是两个 Vue 全局组件,必定是在 vue-router 中实现了全局定义两个组件,他们分别用来跳转路由和展示路由对应的组件内容。

点击 router-link 时导致路由变了,vue-router 内部必然是在监听路由变化,根据路由规则找到匹配的组件,然后在 router-view 中渲染。

所以,路由切换最终是页面的不同组件的展示,而没有真正去刷新页面。

1. vue-router 核心实现原理

目标:

(1)实现一个静态 install 方法,因为作为插件都必须有这个方法,给 Vue.use() 去调用;

(2)可以监听路由变化;

(3)解析配置的路由,即解析router的配置项routes,能根据路由匹配到对应组件;

(4)实现两个全局组件router-linkrouter-view;(最终落地点)

2. 核心代码实现简版

let Vue;
class KVueRouter {
    constructor(options){
        this.$options = options;
        this.$routerMap = {};	//{"/":{component:...}}
        // url 响应式,当值变化时引用的地方都会刷新
        this.app = new Vue({
            data:{
                current: "/"
            }
        });
    }
    // 初始化
    init(){
        // 监听事件
        this.bindEvent();
        // 解析路由
        this.createRouteMap();
        // 声明组件
        this.initComponent();
    }
    bindEvent(){
        window.addEventListener('hashchange', this.onHashchange.bind(this));
    }
    onHashchange(){
        this.app.current = window.location.hash.slice(1) || "/";
    }
    createRouteMap(){
        this.$options.routes.forEach( route => {
            this.$routerMap[route.path] = route;
        })
    }
    initComponent(){
        Vue.component('router-link',{
            props:{
                to: String,
            },
            render(h){
                return h('a', {attrs: {href: '#' + this.to}}, [this.$slots.default])
            }
        });
        Vue.component('router-view',{
            render:(h)=>{
                const Component = this.$routerMap[this.app.current].component;
                return h(Component)
            }
        });
    }
}
// 参数是vue构造函数,Vue.use(router)时,执行router的install方法并把Vue作为参数传入
KVueRouter.install = function(_vue){
    Vue = _vue;
    //全局混入
    Vue.mixin({
        beforeCreate(){//拿到router的示例,挂载到vue的原型上
            if (this.$options.router) {
                Vue.prototype.$router = this.$options.router;
                this.$options.router.init();
            }
        }
    })
}
export default KVueRouter;

解读如下:

  • Vue.use(Router)时,会调用routerinstall方法并把Vue类传入,混入beforeCreate方法,即在Vue实例化后挂载前在vue原型上挂个$router方法,然后调用router实例的init方法;
  • init中把三件事情都干了,监听路由,解析路由(路由mapping匹配),定义组件
  • 需要注意的是,存储当前路由的变量this.app.current非一般的变量,而是借用Vue的响应式定义的,所以当路由变化时只需要给这个this.app.current赋值,而router-view组件刚好引用到这个值,当其改变时所有的引用到的地方都会改变,则得到的要展示的组件也就响应式的变化了。
Vue.js 文章被收录于专栏

Vue.js

全部评论

相关推荐

点赞 评论 收藏
分享
Twilight_m...:表格简历有点难绷。说说个人看法: 1.个人基本情况里好多无意义信息,什么婚姻状况、健康状况、兴趣爱好、户口所在地、身份证号码、邮政编码,不知道的以为你填什么申请表呢。 2.校内实践个人认为对找工作几乎没帮助,建议换成和测开有关的项目,实在没得写留着也行。 3.工作经历完全看不出来是干什么的,起码看着和计算机没啥关系,建议加强描述,写点你在工作期间的实际产出、解决了什么问题。 4.个人简述大而空,看着像AI生成,感觉问题最大。“Python,C,C++成为我打造高效稳定服务的得力工具”、“我渴望凭借自身技术知识与创新能力,推动人工智能技术的应用发展,助力社会实现智能化转型”有种小学作文的美感。而且你确定你个人简述里写的你都会嘛?你AI这块写的什么“深入研究”,发几篇顶会的硕博生都不一定敢这么写。而且你AI这块的能力和软测也完全无关啊。个人简述建议写你对哪些技术栈、哪些语言、哪些生产工具的掌握,写的有条理些,而且最好是和测开强相关的。
点赞 评论 收藏
分享
评论
1
2
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务