最近也在观察vue3新特性,抽空玩一玩嵌套路由的vue-router,直接上代码
<template>
<div id="app">
<div>
<router-link to="/">Index</router-link> |
<router-link to="/person">Person</router-link> |
<router-link to="/person/info">PersonInfo</router-link>
</div>
<!-- 一级路由 -->
<router-view />
</div>
</template>
<style>
#app{ display: flex; flex-direction: column; align-items: center;}
</style>
<template>
<div class="index">
<h1>this is index page</h1>
</div>
</template>
<template>
<div class="person">
<h1>this is person page</h1>
<!-- 二级路由 -->
<router-view />
</div>
</template>
<template>
<div class="personInfo">
<h2>this is personInfo page</h2>
</div>
</template>
import Vue from 'vue'
import App from './App.vue'
import router from './router'
new Vue({
router,
render: h => h(App)
}).$mount('#app')
npm install --save-dev @babel/core @babel/cli
npm install --save-dev @babel/plugin-proposal-optional-chaining
module.exports = {
presets: [ '@babel/preset-env' ],
plugins: ['@babel/plugin-proposal-optional-chaining']
}
import Vue from "vue";
import VueRouter from "./vue-router";
import Index from "../views/Index.vue";
import Person from "../views/Person.vue";
import PersonInfo from "../views/PersonInfo.vue";
Vue.use(VueRouter);
const routes = [
{
path: "/",
name: "Index",
component: Index
},
{
path: "/person",
name: "Person",
component: Person,
children:[
{
path: "/person/info",
name: "PersonInfo",
component: PersonInfo
}
]
}
];
const router = new VueRouter({
routes
});
export default router;
Vue.util.defineReactive
实现数据响应式,后续再手撕这个库import routerLink from "./router-link";
import routerView from "./router-view";
let Vue;
class VueRouter {
constructor(options) {
this.$options = options
this.current = window.location.hash.slice(1) || "/"
// 设置响应式数组数据
Vue.util.defineReactive(this, "routerArray", [])
// 监听hash值变化
window.addEventListener("hashchange", this.hashChange.bind(this))
this.getRouterArray()
}
hashChange() {
this.current = window.location.hash.slice(1) || "/"
this.routerArray = []
this.getRouterArray()
}
getRouterArray(routes) {
routes = routes || this.$options.routes
for (const route of routes) {
if (this.current === '/' && route.path === '/') {
this.routerArray.push(route)
return
}
if (this.current.indexOf(route.path) !== -1 && route.path !== '/') {
this.routerArray.push(route)
if (route.children) {
// 递归子路由
this.getRouterArray(route.children)
}
return
}
}
}
}
VueRouter.install = function(_Vue) {
Vue = _Vue
// Vue全局混入,等new Vue中的router实例创建之后挂载到Vue上
Vue.mixin({
beforeCreate() {
if (this.$options.router) {
Vue.prototype.$router = this.$options.router
}
},
});
// 注册router-link和router-view全局组件
Vue.component("router-link", routerLink)
Vue.component("router-view", routerView)
}
export default VueRouter
export default {
props: {
to: {
type: String,
required: true
}
},
render(h) {
return h(
"a",
{
attrs: {
href: "#" + this.to,
},
},
this.$slots.default
);
}
};
export default {
render(h) {
// 设置嵌套路由标识
this.$vnode.data.rv = true
// 嵌套路由设置深度
let depth = 0
let parent = this.$parent
while (parent) {
// 上级还有嵌套路由标识rv为true的,深度加一
if (parent.$vnode?.data?.rv) {
depth++
}
parent = parent.$parent
}
// 简单处理
const route = this.$router.routerArray[depth]
return h(route?.component);
}
};
好了,今天就玩到这里了,下次再玩别的哈
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有