实现简单版VueRouter嵌套路由

本文详细介绍了如何在VueRouter的基础上实现嵌套路由功能,包括解析matched数组、路由深度标记以及router-view的渲染。通过修改krouter/index.js的路由配置和about.vue页面,实现了子路由的添加。在router-view组件中,利用while循环查找路由深度,并根据matched数组渲染对应组件。文章适合于想要深入学习VueRouter嵌套路由的开发者。
摘要由CSDN通过智能技术生成

实现简单版VueRouter嵌套路由

介绍

本文是承接上文《实现简单版VueRouter》的扩大版,在原有基础上加入嵌套路由功能,以用于更深入的学习VueRouter。多有不足之处,请多多交流。

内容拆分

实现VueRouter的嵌套路由功能,主要有两点:

  • 路由匹配时获取代表深度层级的matched数组

    • router-view深度标记

插件测试

修改路由信息以供实现过程中输出信息查看,也便于发现错误问题。

  • 修改 krouter/index.js 中路由信息
// 修改前
{
    path: "/about",
    name: "About",
    component: () => import("../views/About.vue"),
}
// 修改后
{
    path: "/about",
    name: "About",
    component: () =>import("../views/About.vue"),
    children:[
        {
            path: "/about/info",
            component: {
              render(h) {
                return h('div', 'info page')
              },
            }
        }
    ]
  },
  • 修改 about.vue 页面
<!--修改前-->
<div class="about">
    <h1>This is an about page</h1>
    <router-view></router-view>
</div>
<!--修改后-->
<div class="about">
    <h1>This is an about page</h1>
    <router-view></router-view>
</div>

功能实现

matched数组和match方法

matched数组建立

由于是嵌套路由,所以需要在路由变化时找到当前路由相关的路由信息保存起来。而因为嵌套层级的不确定性需要以数组形式进行保存。

该数组的能力囊括了上一篇文中的current的作用,所以在这里将current废弃掉。

// 修改前
const current = window.location.hash.slice(1) || '/';
Vue.util.defineReactive(this, 'current', current)
// 修改后
this.current = window.location.hash.slice(1) || '/';
Vue.util.defineReactive(this, 'matched', []);
match方法

matched数组建立后,需要执行一定操作根据当前地址栏路由路径将匹配的路由信息填充到数组中。

为了便于递归操作,给match方法添加routes参数。

match(routes) {
    routes = routes || this.$options.routes;
    // 递归遍历
    for (const route of routes) {
      if (route.path === '/' && this.current === '/') {
        // 该情况下为首页匹配
        this.matched.push(route);
        return;
      }
      if (route.path != '/' && this.current.indexOf(route.path) != -1) {
        this.matched.push(route);
        if (route.children) {
          this.match(route.children)
        }
        return;
      }
    }
  }

路由深度标记

在router-view组件中进行路由的深度进行标记,再从matched数组中获取到对应的组件信息,通过render函数渲染出来。

  export default {
  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) {
        if (vnodedata.routerView) {
          // 说明当前parent是一个router-view
          depth++;
        }
      }
      parent = parent.$parent;
    }
    // 获取匹配path的component
    let component = null;
    const route = this.$router.matched[depth];
    if (route) {
      component = route.component;
    }
    return h(component);
  },
}

这一部分的重点在于while循环查找,当前的this指向路由显示页面的router-view组件,通过循环不断的向上查找从而确定路由的深度,还是要多加思考和理解。

App组件 2

div#app 3

a# 4

a#/about 5

about组件 6

div.about 7

router-view 8

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端SkyRain

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值