动态路由使用

时间:2024-03-03 14:13:33

目录

添加动态路由

添加单个路由

添加多个路由

指定路由添加的位置

导航守卫添加路由

删除动态路由


添加动态路由

添加动态路由的方法有两个:addRoutes(添加多个路由)和addRoute(添加单个路由),但是addRoutes只能vue2用,并且已经过时了,所以推荐用addRoute

添加单个路由
  • getRoutes()  可以查看所有路由

  • hasRoute()   可以查看是否有某路由

<template>
  <main>
    <el-button @click="addRoutes">添加动态路由</el-button>
    <el-button @click="toDemo01">跳转Demo01</el-button>
  </main>
</template>

<script setup lang="ts">
import { useRouter } from 'vue-router'

const r = useRouter()

const addRoutes = () => {
  r.addRoute({
    path: '/demo01',
    name: 'demo01',
    component: () => import('@/views/Demo01.vue'),
  })
  
  // 查看所有路由
  console.log(r.getRoutes());
  // 查看是否存在某路由
  console.log(r.hasRoute('demo01'));
}

const toDemo01 = () => {
  r.push('/demo01')
}
</script>

还可以添加嵌套路由

  • 有一点需要注意:路由规则配置文件里,子路由可以不写前面的父路由路径,但是动态路由里不行,必须写完整路径
<template>
  <main>
    <h2>Home</h2>
    <el-button @click="addRoutes">添加动态路由</el-button>
    <el-button @click="toDemo02">跳转Demo02</el-button>
  </main>
</template>

<script setup lang="ts">
import { useRouter } from 'vue-router'

const r = useRouter()

const addRoutes = () => {
  r.addRoute({
    path: '/demo01',
    name: 'demo01',
    children: [
      {
        path: '/demo01/demo02', // 子路由一定要完整 只写/demo02会报错查找不到路由
        name: 'demo02',
        component: () => import('@/views/Demo02.vue'),
      }
    ]
  })

  // 查看所有路由
  console.log(r.getRoutes());
  // 查看是否存在某路由
  console.log(r.hasRoute('demo02'));
}

const toDemo02 = () => {
  r.push('/demo01/demo02')
}
</script>

还可以添加动态路由

<template>
  <main>
    <el-button @click="addRoutes">添加动态路由</el-button>
    <el-button @click="toDemo01">跳转Demo01</el-button>
  </main>
</template>

<script setup lang="ts">
import { useRouter } from 'vue-router'

const r = useRouter()

const addRoutes = () => {
  r.addRoute({
    path: '/demo01/:id', // 还可以添加动态路由  路由只要是  ” /demo01/任意路由 “  都可以匹配到Demo01组件
    name: 'demo01',
    component: () => import('@/views/Demo01.vue'),
  })

  // 查看所有路由
  console.log(r.getRoutes());
  // 查看是否存在某路由
  console.log(r.hasRoute('demo01'));
}

const toDemo01 = () => {
  // r.push('/demo01/1')
  r.push('/demo01/100')
}
</script>
添加多个路由

添加多个动态路由,可以把所有路由对象组成一个数组,对数组进行遍历,然后挨个添加

<template>
  <main>
    <el-button @click="addRoutes">添加动态路由</el-button>
    <el-button @click="toDemo01">跳转Demo01</el-button>
    <el-button @click="toDemo02">跳转Demo02</el-button>
  </main>
</template>

<script setup lang="ts">
import { useRouter } from 'vue-router'
import Demo01 from '@/views/Demo01.vue'
import Demo02 from '@/views/Demo02.vue'

const r = useRouter()

const addRoutes = () => {
  // 路由信息组成的数组
  const routeList = [
    {
      path: '/demo01',
      name: 'demo01',
      component: Demo01
    },
    {
      path: '/demo02',
      name: 'demo02',
      component: Demo02
    },
  ]

  // 只能遍历挨个添加
  routeList.forEach((item: any) => r.addRoute(item))

  // 查看所有路由
  console.log(r.getRoutes());
  // 查看是否存在某路由
  console.log(r.hasRoute('demo01'));
  console.log(r.hasRoute('demo02'));
}

const toDemo01 = () => {
  r.push('/demo01')
}

const toDemo02 = () => {
  r.push('/demo02')
}
</script>
指定路由添加的位置
  • 也就是可以指定路由添加到那个路由下面,addRoute第一个参数指定要添加到那,第二个参数正常的写路由信息

路由配置文件

import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    {
      path: '/',
      name: 'home',
      component: HomeView
    },
    {
      path: '/about',
      name: 'about',
      component: () => import('../views/AboutView.vue')
    }
  ]
})

export default router

我们希望路由添加到about路由里面,成为about的子路由

<template>
  <main>
    <el-button @click="addRoutes">添加动态路由</el-button>
    <el-button @click="toDemo01">跳转Demo01</el-button>
  </main>
</template>

<script setup lang="ts">
import { useRouter } from 'vue-router'

const r = useRouter()

const addRoutes = () => {
  r.addRoute('about', {
    path: '/about/demo01', // 这里路由一定要写完整。路由规则配置文件里,子路由可以不写前面的路由路径,但是动态路由里不行,必须写完整路径
    name: 'demo01',
    component: () => import('@/views/Demo01.vue'),
  })

  // 查看所有路由
  console.log(r.getRoutes());
  // 查看是否存在某路由
  console.log(r.hasRoute('demo01'));
}

const toDemo01 = () => {
  r.push('/about/demo01')
}
</script>
导航守卫添加路由

一般做前端权限的时候用,添加后应该通过返回新的位置来触发重定向,不然地址栏输入路由不会跳转

router.beforeEach(to => {
  if (!hasNecessaryRoute(to)) {
    router.addRoute(generateRoute(to))
    // 触发重定向
    return to.fullPath
  }
})
  • hasNecessaryRoute(to)这个方法是避免重定向的,函数结果返回一个布尔值就行了。to参数携带了要前往路由的具体信息,如果是已经添加过的动态路由,应该返回false,避免重复添加,造成路由重定向,如果没有添加过,则应该返回true,进行动态路由的添加

举个例子,hasNecessaryRoute函数可以这样写

const hasNecessaryRoute = (to: any) => {
  // return router.getRoutes().some(route => route.path === to.path)
  // 或者下面这样
  return router.hasRoute(to.name)
}

前端权限思想

只是大致写了下思路,方法千奇百怪,能实现就行

1. 点击登录的时候,调用接口,后端返回此用户的路由信息,

2. 跳转路由到首页,然后触发全局前置导航守卫

3. 在全局前置导航守卫中进行动态路由的添加

删除动态路由

通过添加一个名称冲突的路由。如果添加与现有途径名称相同的途径,会先删除路由,再添加路由
 

router.addRoute({ path: '/about', name: 'about', component: About })
// 这将会删除之前已经添加的路由,因为他们具有相同的名字且名字必须是唯一的
router.addRoute({ path: '/other', name: 'about', component: Other })

通过使用 router.removeRoute() 按名称删除路由

router.addRoute({ path: '/about', name: 'about', component: About })
// 删除路由
router.removeRoute('about')

注意:当路由被删除时,所有的别名和子路由也会被同时删除