手撸vue-router 更好的理解vue-router的原理

从vue中引入需要使用的api

1
import { ref, inject } from "vue";

1. 定义全局提供router数据的key

1
const ROUTER_KEY = "__router__";

2. createRouter:创建一个router, 接收传入的options,并且return出去一个 Router实例,Router对象通过传入的options实例化自己

1
2
3
function createRouter(options) {
  return new Router(options);
}

3. useRouter  开发人员通过调用useRouter函数来拿到全局提供的Router对象

1
2
3
function useRouter() {
  return inject(ROUTER_KEY);
}

4. createWebHashHistory

通过调用createWebHashHistory来创建一个History路由
这个方法返回了bindEvents函数用来绑定hashchange,路由改变时触发
同时返回了url,值为初始值
1
2
3
4
5
6
7
8
function createWebHashHistory() {
  return {
    bindEvents: (fn) => {
      window.addEventListener("hashchange", fn);
    },
    url: window.location.hash.slice(1) || "/",
  };
}

5. Router对象

options对象上包含开发人员传入的参数:
1
2
3
4
{
history:createWebHashHistory()
routes
}

可以看到history的值是调用了createWebHashHistory函数,拿到了返回值并传给createRouter
routes则是路由列表

再看Routes函数内部,通过内部变量保存了history, routes, currrent
而current通过vue提供的ref api把history.url值拿过来保存起来
current为响应式数据
这里history.url有点绕,建议多看几遍代码

最后调用history上面的bindEvents方法,注册一个函数,在路由改变触发hashchange事件时,更新current

最后install方法
在vue.use时会调用install方法进行组件注册,这时使用最顶层组件app.provide提供数据给任意子组件使用
子组件通过useRouter方法获取

通过在install方法中全局注册router-link组件和router-view组件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Router {
  constructor(options) {
    this.history = options.history;
    this.routes = options.routes;
    this.current = ref(this.history.url);
 
    this.history.bindEvents(() => {
      this.current.value = window.location.hash.slice(1);
    });
  }
  install(app) {
    app.provide(ROUTER_KEY, this);
    app.component("router-link", RouterLink);
    app.component("router-view", RouterView);
  }
}

6. 最后导出api提供给开发人员使用

1
export { createRouter, createWebHashHistory, useRouter }

完整代码

下两篇文章:RouterLink,RouterView

posted @   大厨的笔记  阅读(277)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端
点击右上角即可分享
微信分享提示