
手写vue-router源码
发布日期:2021-05-13 22:21:39
浏览次数:21
分类:精选文章
本文共 4595 字,大约阅读时间需要 15 分钟。
手写Vue Router源码实现
一、项目准备
1. 创建Vue项目
使用vue create
命令创建一个新的Vue项目:
vue create projectName
进入项目目录:
cd projectName
2. 安装Vue Router
使用vue add router
命令安装Vue Router:
vue add router
3. 手写Vue Router源码
在router
文件夹中创建jvue-router.js
文件。
let Vue;class VueRouter { constructor(options) { this.options = options; this.current = window.location.hash.slice(1) || "/"; Vue.util.defineReactive(this, "current", this.current); this.match(); window.addEventListener("hashchange", () => { this.current = window.location.hash.slice(1); this.matched = []; this.match(); }); } match() { const routes = this.options.routes || []; let matched = []; for (const route of routes) { if (route.path === "/" && this.current === "/") { matched.push(route); return; } if (route.path !== "/" && this.current.indexOf(route.path) !== -1) { matched.push(route); if (route.children) { this.match(route.children); } return; } } this.matched = matched; }}VueRouter.install = function(_vue) { Vue = _vue; Vue.mixin({ beforeCreate() { if (this.$options.router) { Vue.prototype.$router = this.$options.router; } } }); Vue.component("router-view", { render(h) { this.$vnode.data.routerView = true; let depth = 0; let parent = this.$parent; while (parent) { const vnodeData = parent.$vnode && parent.$vnode.data; if (vnodeData && vnodeData.routerView) { depth++; } parent = parent.$parent; } const route = this.$router.matched[depth]; return h(route ? route.component : "div"); } }); Vue.component("router-link", { props: { to: { type: String, required: true } }, render(h) { return h("a", { attrs: { href: "#" + this.to } }, this.$slots.default); } });};export default VueRouter;
4. 路由组件注册
在index.js
中引入自定义的Vue Router:
// import VueRouter from "vue-router";import VueRouter from "./jvue-router";
5. 嵌套路由实现
在router/index.js
中添加嵌套路由:
const routes = [ { path: "/", name: "Home", component: Home }, { path: "/about", name: "About", component: () => import("../views/About.vue"), children: [ { path: "/about/intro", name: "Intro", component: { render: h => h("div", "intro page") } } ] }];const router = new VueRouter({ routes });
在views/About.vue
中添加router-view
组件:
This is an about page
6. 嵌套路由优化
在jvue-router.js
中优化路由匹配逻辑:
class VueRouter { constructor(options) { this.options = options; this.current = window.location.hash.slice(1) || "/"; Vue.util.defineReactive(this, "current", this.current); this.matched = []; this.match(); window.addEventListener("hashchange", () => { this.current = window.location.hash.slice(1); this.matched = []; this.match(); }); } match() { const routes = this.options.routes || []; let matched = []; for (const route of routes) { if (route.path === "/" && this.current === "/") { matched.push(route); return; } if (route.path !== "/" && this.current.indexOf(route.path) !== -1) { matched.push(route); if (route.children) { this.match(route.children); } return; } } this.matched = matched; }}VueRouter.install = function(_vue) { Vue = _vue; Vue.mixin({ beforeCreate() { if (this.$options.router) { Vue.prototype.$router = this.$options.router; } } }); Vue.component("router-view", { render(h) { this.$vnode.data.routerView = true; let depth = 0; let parent = this.$parent; while (parent) { const vnodeData = parent.$vnode && parent.$vnode.data; if (vnodeData && vnodeData.routerView) { depth++; } parent = parent.$parent; } const route = this.$router.matched[depth]; return h(route ? route.component : "div"); } }); Vue.component("router-link", { props: { to: { type: String, required: true } }, render(h) { return h("a", { attrs: { href: "#" + this.to } }, this.$slots.default); } });};export default VueRouter;
路由使用说明
1. 简单路由示例
About
2. 嵌套路由示例
Intro
3. 路由参数传递
可以通过to
属性传递额外的路由参数:
User Profile (123)
发表评论
最新留言
哈哈,博客排版真的漂亮呢~
[***.90.31.176]2025年04月08日 13时12分03秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
国标流媒体服务器以ROOT身份运行提示“permission denide”报错解决
2019-03-10
qt中转到槽后如何取消信号与槽关联
2019-03-10
qt问题记录-spin box与double spin box
2019-03-10
移动端事件
2019-03-10
css 图片按比例缩放
2019-03-10
小程序form表单里面buton点击事件失效
2019-03-10
微信小程序placeholder设置自定义样式
2019-03-10
spring-day01
2019-03-10
spring的值注入与组件扫描
2019-03-10
C#跨窗体程序调用方法的具体操作
2019-03-10
C#中创建Android项目
2019-03-10
统计学之变异系数与是非标志
2019-03-10
关于继承的一些基本知识
2019-03-10
抖音发布黄金时间段,抖音上热门最佳时间
2019-03-10
我的图床~
2019-03-10
Thymeleaf sec:authorize 标签不生效
2019-03-11
Iterable与Iterator
2019-03-11
Python机器学习(六十五)Matplotlib 入门
2019-03-11