在搭建后台管理系统时,我想要实现一个动态路由的效果,动态的数据由后端的接口返回,我拿到后端返回的数据后,发现他没有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
<template>
<div class="leftSlider">
<el-menu
:default-active="authPath"
class="el-menu-vertical-demo"
background-color="#304156"
text-color="#fff"
active-text-color="#ffff00"
:collapse-transition="true"
:unique-opened="true"
:router="true"
@open="handleOpen"
@close="handleClose"
:collapse="isCollapse">
<el-menu-item index="/index">
<i class="el-icon-location"></i>
<span slot="title">首页</span>
</el-menu-item>
<el-submenu v-for="(item,index) in sidebarRouters" :index="item.id+''" :key="index">
<template slot="title">
<i :class="Icon[item.id]"></i>
<span>{{item.authName}}</span>
</template>
<el-menu-item v-for="(item2,index2) in item.children" :index="'/'+item2.path+''" :key="index2"
>
<template slot="title" v-if="!item2.hidden">
<i class="el-icon-menu"></i>
<span slot="title">{{item2.authName}}</span>
</template>
</el-menu-item>
</el-submenu>
</el-menu>
</div>
</template>
<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的路径,并且能正确的跳转页面呢,想要大家帮我解下题,困扰好久了