Vue 动态路由,使用 addRoute 添加(分享)

本文详细介绍了Vue.js中的静态路由和动态路由实现。静态路由适用于初始配置,但可能存在用户直接通过地址栏访问未授权页面的问题。动态路由则根据用户权限动态添加路由,解决这一问题。在登录时,通过路由前置守卫和用户token获取权限信息,动态加载用户可访问的页面。代码示例展示了如何配置和实现这两种路由策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 静态路由

1.1 概述
  • 已经确定了路由的数量(一般是侧边栏的路由),最开始可以把路由表配置好
  • 如果后期有权限的情况的下,也可以只展示对应的菜单,使用路由懒加载的话,没有对应菜单的路由就不会渲染
  • 但是这样做就会存在一个问题,用户通过地址栏输入路由路径,也可以访问到对应页面
1.2 代码实现
// 最开始就把路由给配置好
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)

import Login from "../page/login/Login.vue"

const routes = [
  {
    path: "/",
    redirect: "/login",
  },
  {
    path: "/login",
    component: Login
  },
  {
    name: "index",
    path: "/",
    component: () => import("../page/container/Container.vue"),
    children: [
      {
        path: "addGoods",
        component: () => import("../page/goods/AddGoods.vue")
      },
      {
        path: "dashbord",
        component: () => import("../page/dashbord/Dashbord.vue")
      },
      {
        path: "users",
        component: () => import("../page/users/Users.vue")
      },
      {
        path: "roles",
        component: () => import("../page/rights/Roles.vue")
      },
      {
        path: "rights",
        component: () => import("../page/rights/Rights.vue")
      },
      {
        path: "goods",
        component: () => import("../page/goods/Goods.vue")
      },
      {
        path: "params",
        component: () => import("../page/goods/Params.vue")
      },
      {
        path: "categories",
        component: () => import("../page/goods/Categories.vue")
      },
      {
        path: "orders",
        component: () => import("../page/orders/Orders.vue")
      },
      {
        path: "reports",
        component: () => import("../page/reports/Reports.vue")
      }
    ]
  }
]

const router = new VueRouter({
  mode: "history",
  routes
})

export default router

2. 动态路由

2.1 概述
  • 为了解决静态路由所带来的问题,动态路由是当前用户拥有哪些访问的权限才添加对应的路由
  • 登录的时候,在路由前置守卫中通过 token 来获取该用户存在哪些权限,在依次添加
2.2 代码实现
// index.js 文件
// 把固定的路由先配置好
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)

import Login from "../page/login/Login.vue"

export const routes = [
  {
    path: "/",
    redirect: "/login",
  },
  {
    path: "/login",
    component: Login
  },
  {
    name: "index",
    path: "/",
    component: () => import("../page/container/Container.vue"),
    children: [
      {
        path: "addGoods",
        component: () => import("../page/goods/AddGoods.vue")
      },
      {
        path: "dashbord",
        component: () => import("../page/dashbord/Dashbord.vue")
      },
    ]
  }
]

const router = new VueRouter({
  mode: "history",
  routes
})

// 向 router 上添加一个,重新实例化 VueRouter 的方法
router.reloadRouter = function () {
  router.matcher = new VueRouter({
    mode: "history",
    routes
  }).matcher
}

export default router
// permission.js 文件
import router from "../router/index"
import store from "../store/index"
// 请求的权限数据
import { menus } from "../api/roles/index";

// 首字母转大写
function firstUppercase(str) {
  return str[0].toUpperCase() + str.substring(1)
}

// 权限存储
function getRights() {
  menus()
    .then((res) => {
      store.dispatch("asyncGetRights", res);
      routesData(res)
    })
    .catch((err) => {
      console.error(err);
    });
}

// 动态添加路由
function routesData(data) {
  // 重新加载一次 VueRouter
  router.reloadRouter()
  data.forEach(item => {
    item.children.forEach(i => {
      // 组装路由配置
      const temp = {
        name: i.path,
        path: i.path,
        component: () => import(`../page/${item.path}/${firstUppercase(i.path)}.vue`)
      }
      // 动态添加为 index 的子路由
      router.addRoute("index", temp)
    })
  })
  // 动态添加一个 404 页面
  router.addRoute({
    path: "*",
    component: () => import("../page/404/404.vue")
  })
}

// 有 token 不能去登录页,没有 token 只能去登录页 
router.beforeEach((to, from, next) => {
  const token = store.state.token
  if (token) {
    // 如果有 token 并且不是登录页的时候,进行权限获取
    if (to.path !== "/login") {
      // 动态路由只能添加一次
      // 退出登录后可重新添加
      if (!store.state.isRights) {
        store.state.isRights = true
        getRights()
      }
    }
    if (to.path === "/login") {
      next("/dashbord")
    }
  } else {
    if (to.path !== "/login") {
      next("/login")
    }
  }
  next()
})
### Vue动态添加嵌套路由Vue 应用程序中,动态添加嵌套路由可以通过修改路由配置并在运行时更新路由器实例来实现。以下是具体的操作方法: #### 创建基础路由配置 首先,初始化应用程序的基础路由配置文件 `router/index.js` 或者类似的路径下。 ```javascript import { createRouter, createWebHistory } from 'vue-router' import ParentComponent from '../components/ParentComponent.vue' const routes = [ { path: '/parent', name: 'Parent', component: ParentComponent, children: [] // 初始为空的子路由列表 } ] const router = createRouter({ history: createWebHistory(), routes }) export default router ``` #### 动态添加路由函数 为了能够灵活地向已有的父级路由中增加新的子路由项,编写一个用于动态注册新子路由的方法。 ```javascript function addDynamicChildRoute(parentPath, childRouteConfig) { const parentRecord = router.getRoutes().find(route => route.path === parentPath); if (parentRecord && Array.isArray(parentRecord.children)) { parentRecord.children.push(childRouteConfig); // 更新路由表以反映更改后的结构 router.addRoute(parentPath, childRouteConfig); } else { console.error(`未能找到指定路径 ${parentPath} 的父级记录`); } } ``` 此段代码会查找给定路径对应的父级路由条目,并在其内部追加一个新的子路由配置对象[^1]。 #### 使用场景示例 假设有一个按钮点击事件触发上述逻辑,则可以在组件内这样调用该方法: ```html <template> <div> <!-- 假设这是某个视图内的按钮 --> <button @click="addChildRoute">Add Child Route</button> <router-view></router-view> <!-- 显示当前匹配到的内容 --> </div> </template> <script setup> import { ref } from 'vue'; // 导入前面定义好的辅助函数 import { useRoute, useRouter } from 'vue-router'; let count = ref(0); function addChildRoute() { let newChildRoute = { path: `child-${++count.value}`, name: `Child${count.value}`, component: () => import('../views/DynamicChildView.vue') // 按需加载组件 }; addDynamicChildRoute('/parent', newChildRoute); } // 初始化路由实例供后续操作使用 const router = useRouter(); </script> ``` 当用户每次点击按钮时都会往 `/parent` 下面新增一条名为 `child-x` (其中 x 是自增序号)的新子路由,并且这些子路由会被立即生效显示出来[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值