使用后端返回的数据实现动态路由,但是返回的数据中没有component

在搭建后台管理系统时,我想要实现一个动态路由的效果,动态的数据由后端的接口返回,我拿到后端返回的数据后,发现他没有component,这个时候我怎么给返回的数据添加一个component的路径,并且能正确的跳转页面呢?

router/index.js

import Vue from 'vue'
import Router from 'vue-router'
import Layout from '../layout/index'
Vue.use(Router)

// 公共路由
export const constantRoutes = [
    {
        path:'/redirect',
        component:Layout,
        hidden:true,
        children:[
            {
                path:'/redirect/:path(.*)',
                component:()=>import('@/view/redirect')
            }
        ]
    },
    {
        path:'/login',
        name:'Login',
        component:()=>import('@/view/login'),
        hidden:true
    },
    {
        path:'',
        component:Layout,
        redirect:'index',
        hidden: true,
        children:[
            {
                path:'/index',
                component:()=>import('@/view/Home'),
                name:'Index',
                meta:{title:'首页',affix:true}
            }
        ]
    },
    {
        path:'/personal',
        component:Layout,
        redirect:'noredirect',
        hidden: true,
        children:[
            {
                path:'personal',
                component:()=>import('@/view/admin/index'),
                name:'personal ',
                meta:{title:'个人中心',affix:true}
            }
        ]
    }
]

const router = new Router({
    mode:'history',
    routes:constantRoutes,
    scrollBehavior:()=>({
        y:0
    })
})
export default router

routers/router.js
import router from './index'
import store from '@/store'
import { getToken } from '@/until/auth'
// import { isRelogin } from '@/until/index'

const whiteList = ['/login','/auth-redirect']

router.beforeEach((to,from,next)=>{
    // 判断当前用户是否登陆
    if(getToken()){
        if(to.path==='/login'){
            next()
        }else{
            if(store.getters.sidebarRouters.length===0){
                store.dispatch('GenerateRoutes').then(res=>{
                    router.addRoutes(res)
                    next({...to,replace:true})
                }).catch((err)=>{
                    next({path:'/'})
                })
            }else{
                next()
            }
        }
    }else{
        // 用户未登录
        if(whiteList.indexOf(to.path)!==-1){
            // 用户跳转的是否是whiteList中的路由,如果是就跳转
            next()
        }else{
            // 需要跳转的路由不是whiteList中的,就跳转到login
            next(`/login?redirect=${to.path}`)
        }
    }
})

store/permission.js
import auth from '@/plugins/auth'
import router,{constantRoutes} from '@/routers'
import Layout from '@/layout/index'
import {getMenus} from '@/api/menu'
 
const permission = {
    state:{
        routes:[],
        addRoutes:[],
        defultRouters:[],
        topbarRouters:[],
        sidebarRouters:[]
    },
    mutations:{
        SET_ROUTES:(state,routes)=>{
            state.addRoutes = routes
            state.routes = constantRoutes.concat(routes)
        },
        SET_SIDEBAB_ROUTERS:(state,routes) => {
            state.sidebarRouters = routes 
        }
    },
    actions:{
        GenerateRoutes({commit}){
            return new Promise(resolve=>{
                getMenus().then(res=>{
                    const sdata=res.data
                    const rdata=res.data
                    const sidebarRoutes=filterAsyncRouter(sdata)
                    const rewiteRoutes = filterAsyncRouter(rdata,false,true)
                     rewiteRoutes.push({ path:'*', redirect:'/404',hidden:true })
                    commit('SET_ROUTES',rewiteRoutes)
                    commit('SET_SIDEBAB_ROUTERS',constantRoutes.concat(sidebarRoutes))
                    resolve(rewiteRoutes)
                })
            })
        }
    }
}

function filterAsyncRouter(asyncRouterMap,lastRouter=false,type=false){
      asyncRouterMap.filter(route => {
        if(type&&route.children){
            route.children=filterChildren(route.children)
        }
        let Path = ''
        if(route.children&&route.children!=null){
            route.children.forEach(item=>{
                Path = route.path +'/'+ item.path
                route.component=loadView(Path)
            })
        }
        
        if(route.children!=null){
            route.component='Layout'
        }
        // 判断是否存在子路由,并递归调用自己
        if(route.children != null && route.children && route.children.length){
            route.children = filterAsyncRouter(route.children,route,type)
        }
        else{
            delete route['children']
            delete route['redirect']
        }
        return true
    })
}

export const loadView = (view)=>{
    return (resolve)=>require([`@/view/${view}`],resolve)
}

export default permission

slider/index


<script>
    import {mapGetters,mapState} from 'vuex'
export default {
    props: {
        isCollapse: {
          type: Boolean
        }
    },
    computed:{
        ...mapGetters(["sidebarRouters"]),
        authPath(){
            const route = this.$route
            const {meta,path} = route
            if(meta.authPath){
                return meta.authPath
            }
            return path
        }
    },
    data(){
        return{
            Icon:{
                "125":"iconfont icon-icon_user",
                "103":"iconfont icon-danju",
                "101":"iconfont icon-shangpin",
                "102":"iconfont icon-tijikongjian",
                "145":"iconfont icon-baobiao"
            },
            
        }
    },
    created() {
    },
    methods: {
          handleOpen(key, keyPath) {
            console.log(key, keyPath);
            console.log('sidebarRouters1',this.sidebarRouters)
            
            this.sidebarRouters.filter((item)=>{
                console.log('component',item.component)
            })
          },
          handleClose(key, keyPath) {
            console.log(key, keyPath);
          }
    }
}
script>

<style>
    /* .leftSlider{
        height: 100vh;
    } */
    .el-submenu__title,.el-menu-item{
        text-align: initial;
        color:white !important;
    }
    .el-submenu__title:hover,.el-menu-item:hover{
        background-color:#001528 !important;
    }
    .el-menu{
        background-color: #304156 !important;
        border:none !important;
    }
style>
这样实现跳转页面侧边栏没有任何菜单,打印出数据也只有静态的几个数据,由后端返回来的数据没有,而且就算有了也没有办法正确的跳转页面
在获取到后端数据时保存到vuex,然后再vuex数据中判断是否有children,给第一级菜单统一加上layout,给有子菜单的加上自己获取到后端接口path路径拼接传给loadView,但是路径跳转还是不正确
我想要达到的结果

在搭建后台管理系统时,我想要实现一个动态路由的效果,动态的数据由后端的接口返回,我拿到后端返回的数据后,发现他没有component,这个时候我怎么给返回的数据添加一个component的路径,并且能正确的跳转页面呢,想要大家帮我解下题,困扰好久了

断点跟踪一下,数据没返回回来吗

后端返回的没有 component属性 。那你前端 获取到 后 还得手动加 。麻烦的是 你得循环 一个一个判断 然后 手动给 component 赋值。因为不同的 path对应的component 路径也不一样。

或者 你 前端 页面 目录结构都统一 。然后 可以 用变量来 拼接。 再或者 后端连component都返回来 。不过这样 前端 某个组件路径 或者文件名改了 就不行了,后端也得改