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

  • Post author:
  • Post category:vue




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()
})



版权声明:本文为weixin_60547084原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。