手撸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
分类:
vue3
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端