vue2+element-ui 动态路由

前言

在我之前之前的项目中,项目设置的动态路由是通过后端返回的路由权限标识组来进行控制的。

具体代码如下是:

js 复制代码
// router index.js
// 静态路由表
export const constantRoutes = [
  {path: '/login',component: () => import('@/views/login/index'),hidden: true},
  {path: '/404',component: () => import('@/views/404'),hidden: true},
  {
    path: '/',component: Layout,redirect: '/dashboard',
    children: [{path: '/dashboard',name: 'Dashboard',
      component: () => import('@/views/dashboard/index'),meta: { title: '首页', icon: 'dashboard' }}]
  },
]
// 动态路由组
export const MyRouter = [approval,attendance,]

// approval.js
import Layout from '@/layout'
export default {path: '/approval',name: 'approval',component: Layout,
                children: [{path: '',name: 'approval',
                            component: () => import('@/views/approval/index'),
      meta: {icon: 'tree-table',title: '审批管理'}}
  ]}
        
js 复制代码
// permission.js
import router from './router'
import store from './store' 
import { getToken } from '@/utils/auth'
import { MyRouter} from "./router"
const whiteList = ['/login', '/404'] 
router.beforeEach(async(to, from, next) => {
  // 当然这个地方可以加个进度条,我懒得加
  const hasToken = getToken()
  if (hasToken) {
    if (to.path === '/login') {
      next('/')
    } else {
      // 判断是否有数据
      if(!store.getters.userId){
        // 获取用户数据
      let res = await store.dispatch('user/userInfo')
      // 过滤 进行名称匹配
        const filterRoutes = MyRouter.filter(item=>{
          // 过滤出了来的数据 返回出去、
          // 过滤出的权限组 [approval,attendance]
          return res.roles.menus.includes(item.name)
        })
        console.log(filterRoutes);
        // 存储在 vuex 中
        store.commit('user/setRoutes',filterRoutes)
        // 动态添加路由
        router.addRoutes([...filterRoutes,{ path: '*', redirect: '/404', hidden: true }])
        // router动态添加 目的让路由留有信息
        next(to.path)
      }
      next()
    }
  } else {
    if (whiteList.includes(to.path)) {
      next()
    } else {
      next('/login')
    }
  }
})

router.afterEach(() => {
})

但是这种添加路由模式有错误:

1.在高版本中addRoutes已经被废除了,无法在继续使用。

2.动态添加时,必须要加上 404页面路由, 不然就会报错。

当然还有其他的路由权限方法。

使用路由权限对象组 (整个路由对象)来设置用户权限。

具体代码如下:

js 复制代码
// router index.js
Vue.use(VueRouter);

const routes = [
    { name: "login", path: "/login", meta: { title: "登录" }, component: login, hidden: true },
    // { name: "404", path: "/404", meta: { title: "404页面" }, component: import("@/views/404.vue"), hidden: true },
];

const router = new VueRouter({
    mode: 'history',
    base: process.env.BASE_URL,
    routes,
});

// permission.js
import router from '@/router';
import store from '@/store';
import layout from '@/views/layout/index.vue';


const filterRoutes = ["/login", "/404"]  //需要过滤的数组

router.beforeEach(async (to, from, next) => {
    document.title = `${to.meta.title}`; //获取路由中的meta中的title,并设置成页面之间的标题
    // 判断路由跳转的页面是否在白名单中
    // 在, 直接跳转,不需要判断
    if (filterRoutes.indexOf(to.path) !== -1) {
        next();
        return false
    }
    if (router.options.routes.length == 1) {
        // 获取token 和原始路由数组
        const userinfo = await store.dispatch('user/login')
        // 当token和原始路由都存在的时候
        if (userinfo.token && userinfo.routes) onFilterRoutes(to, next, userinfo.routes) // 执行路由过滤和跳转
        else next({ path: "/login", replace: true })
    } else next()
})

// 路由拼接
function loadView(view) {
    console.log(`@/views/${view}.vue`);
    return () => import(`@/views/${view}.vue`)
}
// 路由过滤 及跳转
async function onFilterRoutes(to, next, e) {
    const routes = await filterASyncRoutes(e)
    routes.sort((a, b) => a['id'] - b['id'])//排序
    routes.forEach(item => {
        router.options.routes.push(item)
        router.addRoute(item)
    })

    next({ ...to, replace: true })
}
// 路由过滤   遍历路由 转换为组件对象和路径
function filterASyncRoutes(data) {
    const routes = data.filter((item) => {
        if (item["component"] === "Layout") item.component = layout
        else item["component"] = loadView(item["component"])
        // 路由递归,转换组件对象和路径
        if (item["children"] && item["children"].length > 0) item["children"] = filterASyncRoutes(item.children)
        return true
    })
    console.log(routes);
    return routes
}

数据是先用mock进行模拟的

yaml 复制代码
routes: [
            {
                id: 1, name: "/", path: "/", component: "Layout", redirect: "/home/index", hidden: false, children: [
                    { name: "/home/index", path: "/home/index", meta: { title: "管理首页" }, component: "home/index" }
                ]
            },
            {
                id: 2, name: "/role", path: "/role", component: "Layout", redirect: "/role/index", meta: { title: "权限管理" }, hidden: false, children: [
                    { name: "/index", path: "/role/index", meta: { title: "管理员列表" }, component: "role/index" },
                    { name: "/roleuser", path: "/role/roleuser", meta: { title: "角色管理" }, component: "role/roleuser" }
                ]
            },
            {
                id: 3, name: "/order", path: "/order", component: "Layout", redirect: "/order/index", hidden: false, children: [
                    { name: "/order/index", path: "/order/index", meta: { title: "订单管理" }, component: "order/index" }
                ]
            },
            {
                id: 4, name: "/user", path: "/user", component: "Layout", redirect: "/user/index", hidden: false, children: [
                    { name: "/user/index", path: "/user/index", meta: { title: "用户管理" }, component: "user/index" }
                ]
            },
            {
                id: 5, name: "/commodity", path: "/commodity", component: "Layout", redirect: "/commodity/index", hidden: false, children: [
                    { name: "/commodity/index", path: "/commodity/index", meta: { title: " 商品管理" }, component: "commodity/index" }
                ]
            }
        ]

当然也出现问题。也是最不该的问题

路径名称出现大小写问题。

期初我以为是添加到静态路由表中步进行排查。突然看下文件夹名称,发现我写错了,主要是习惯

大写字母开头。

在之后引以为鉴。

相关推荐
啦啦右一1 分钟前
前端 | MYTED单篇TED词汇学习功能优化
前端·学习
半开半落6 分钟前
nuxt3安装pinia报错500[vite-node] [ERR_LOAD_URL]问题解决
前端·javascript·vue.js·nuxt
理想不理想v34 分钟前
vue经典前端面试题
前端·javascript·vue.js
不收藏找不到我35 分钟前
浏览器交互事件汇总
前端·交互
YBN娜1 小时前
Vue实现登录功能
前端·javascript·vue.js
阳光开朗大男孩 = ̄ω ̄=1 小时前
CSS——选择器、PxCook软件、盒子模型
前端·javascript·css
minDuck1 小时前
ruoyi-vue集成tianai-captcha验证码
java·前端·vue.js
小政爱学习!1 小时前
封装axios、环境变量、api解耦、解决跨域、全局组件注入
开发语言·前端·javascript
魏大帅。1 小时前
Axios 的 responseType 属性详解及 Blob 与 ArrayBuffer 解析
前端·javascript·ajax