1.使用场景

当我们在配置路由结构时,有父子关系时,会这样设计路由

  {
    name: 'testA',
    path: '/testa',
    component:() => import('../views/test/testA.vue'),
    children: [
      {
        name: 'testB',
        path: 'testb',
        component: ()=>import('../views/test/testB.vue'),
      },
      {
        name: 'testC',
        path: 'testc',
        component: ()=>import('../views/test/testC.vue'),
      },
    ]
  },

但渲染的结果是,当我们访问/testa/testb时,会将testA页面和testB页面内容同时展现出来,若我们此时只想渲染testB页面内容,我们可以封装一个这样的js方法

2.封装RouterReplaceSelf方法

utils/routerReplaceSelf.js文件中

import {defineAsyncComponent, h, render} from "vue";
import {  RouterView } from 'vue-router';

export default function RouterReplaceComp(component) {
  return {
    comp:component,
    name: 'routeReplaceSelf',
    computed: {
      // 获取当前页面组件,并将当前组件改为自己的组件
      currentPage() {
        // this.$route.matched[this.$route.matched.length - 1]获取当前匹配的子路由 路径 eg:testa/testb
        const curComp = this.$route.matched[this.$route.matched.length - 1]
        // 当前渲染页面
        const curPage = curComp.components.default.comp
        // 若当前子组件中没有渲染内容
        return curPage === component
      }
    },
    render() {
      // defineAsyncComponent 创建一个在需要时才会加载的异步组件
      // 若不同 则渲染 当前路由所对应的页面   若相同则渲染当前
      return this.currentPage?h(defineAsyncComponent(component)):h(RouterView)
    }
  }
}

代码解析:

  • 当我们在渲染路由对应的内容时,相关的信息会在route中进行体现,我们可以打印一下this.$route查看内部的情况
  • 其中matched对应为一个数组,若父子组件嵌套形式,当前子组件对应的为matched数组中的最后一个元素
  • 最后一个元素中components.default.comp是当前页面渲染的内容,一般无渲染内容为undefined,由于父组件在开始return时,将传入的路径赋给了父组件,所以里面comp是有值的
  • 这样我们在render时,如果当前无渲染内容,就渲染router-view对应的页面内容,若有内容代表没有子组件,就渲染它自己

3.使用

  // TODO:路由配置
  {
    name: 'testA',
    path: '/testa',
    component: RouterReplaceComp(() => import('../views/test/testA.vue')),
    children: [
      {
        name: 'testB',
        path: 'testb',
        component: RouterReplaceComp(()=>import('../views/test/testB.vue')),
        children:[
          {
            name: 'testC',
            path: 'testc',
            component: ()=>import('../views/test/testC.vue'),
          },
        ]
      },

    ]
  },

学习来源,这篇文章超级详细哦~

总结用法,希望可以帮助到你,
我是Ably,你无须超越谁,只要超越昨天的自己就好~

Logo

前往低代码交流专区

更多推荐