vue addRoute(item) 动态路由

686 阅读1分钟
https://gitee.com/jia-ping/lucky_man/tree/master/main/demo/vue2  //项目码云地址
登录页面js及模拟数据
  1. 登录页面js
import dynamicUser from '../assets/mock.js' // 引入模拟数据
submitForm(formName) {
    this.$refs[formName].validate((valid) => {
	if (valid) {
            let flag = !1
            localStorage.removeItem('userInfo') // 每次登录都移除上次的数据
            dynamicUser.forEach(item=>{
                if(item['username'] == this.dataForm['name'] && item['password'] == this.dataForm['pass']){
                flag = !0
                this.$message.success('登录成功!')
                localStorage.setItem('userInfo',JSON.stringify(item))  // 存储当前的登录信息
                this.$router.replace('/')
                }
           })
           if(!flag) this.$message.error('账号密码错误,请重试!')
        } else return false
    })
},

2.mock数据

export default   [
    {
        name: "管理员",
        avatar: "https://sf3-ttcdn-tos.pstatp.com/img/user-avatar/ccb565eca95535ab2caac9f6129b8b7a~300x300.image",
        desc: "管理员 - admin",
        username: "admin",
        password: "654321",
        token: "rtVrM4PhiFK8PNopqWuSjsc1n02oKc3f",
        routes: [
            { id: 1, name: "/", path: "/", component: "Layout", redirect: "/home",meta: { title: "Demo1",icon:'el-icon-eleme' }, hidden: false, children: [
                { name: "home", path: "/home", meta: { title: "home",icon:'el-icon-star-off' }, component: "HomeView" },
                { name: "temp", path: "/temp", meta: { title: "temp",icon:'el-icon-star-off' }, component: "tempA" },
            ]},
            { id: 2, name: "test", path: "/test", component: "Layout", redirect: "/a",meta:{title:'Demo2',icon:'el-icon-star-off'}, hidden: false, children: [
                { name: "a", path: "/a", meta: { title: "A" ,icon:'el-icon-star-off'}, component: "test/a" },
                { name: "b", path: "/b", meta: { title: "B" ,icon:'el-icon-star-off'}, component: "test/b" },
            ]},
        ]
    },
    {
        name: "普通用户",
        avatar: "https://sf1-ttcdn-tos.pstatp.com/img/user-avatar/6364348965908f03e6a2dd188816e927~300x300.image",
        desc: "普通用户 - people",
        username: "people",
        password: "123456",
        token: "4es8eyDwznXrCX3b3439EmTFnIkrBYWh",
        routes: [
            { id: 1, name: "/", path: "/", component: "Layout", redirect: "/c",meta:{title:'user1',icon:'el-icon-star-off'}, hidden: false, children: [
                { name: "c", path: "/c", meta: { title: "C" ,icon:'el-icon-star-off'}, component: "user/c" },
                { name: "d", path: "/d", meta: { title: "D" ,icon:'el-icon-star-off'}, component: "user/d" },
            ]},
            // { id: 2, name: "/form", path: "/form", component: "Layout", redirect: "/form/index", hidden: false, children: [
            //     { name: "/form/index", path: "/form/index", meta: { title: "form" }, component: "form/index" }
            // ]},

        ]
    }
]
基本路由文件配置
import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

const routes = [
    {
        path: '/login',
        name: 'login',
        component: () => import('../views/login.vue'),
        meta:{
            title:'login'
        },
        hidden:true,
    },
]
const router = new VueRouter({
    mode: 'history',
    routes
})

export default router

路由守卫动态路由添加配置
  1. router文件夹中创建router_config.js文件
import router from './index'
import Layout from '../components/layout/index'  // 全局布局组件

const filterRoutes = ['/login'] // 需要过滤掉的路由
router.beforeEach((to, from, next) => {
    // 设置页面标题
    document.title = `addRouter_${to.meta.title}`
    // 跳过需要过滤的路由页面
    if (filterRoutes.indexOf(to.path) !== -1) {
        next()
        return false
    }
    if (router.options.routes.length === 1) {
        // 获取token和原始路由数组 '??'前面的值等于undefined或null时 执行后面的操作
        const userInfo = JSON.parse(localStorage.getItem('userInfo')) ?? ""
        if (userInfo.token && userInfo.routes) {
            onFilterRoutes(to, next, userInfo.routes) 
            next()
        }// 执行路由过滤和跳转
        else next({ path: '/login', replace: true })
    }else next()
})


// 路由过滤和跳转
async function onFilterRoutes (to, next, routes) {
    routes = await filterAsyncRoutes(routes)  // 路由过滤
    routes.sort((a,b)=>a['id']-b['id']) // 按照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
    })
    return routes
}

// 路由拼接
function loadView (view) {
    return () => import(`@/views/${view}`)
}
  1. main.js中引入添加动态路由文件
import "./router/router_config"  // 路由守卫,做动态路由的地方