导语
人生呀 总会有一些改变,入行快2年了,今天来记录下我的第一篇博客,哈哈 不管有没有人看。
开始正题
一、通过后端返回的信息 动态添加路由
首先登录,获取到你的用户信息,把token存在cookies 里面,然后跳转系统首页。在跳转之前我做了一个路由处理 新增了一个 permission.js 直接在main.js 引用就可以了
这个文件用了 router 的 beforeEach ,我是在每次路由请求之前 执行 GetUserInfo,GenerateRoutes 这两个方法,把用户信息和路由信息存到仓库里面。(这是为了防止刷新浏览器后动态添加的菜单不存在了。)
router.beforeEach((to, from, next) => {
NProgress.start() // start progress bar
// debugger
if (getToken()) { //判断是否有token
/* has token */
if (to.path === '/login') {
next({ path: '/' })
NProgress.done() //
} else {
if (store.getters.addRouters.length === 0) {
store.dispatch('GetUserInfo').then(() => {
store.dispatch('GenerateRoutes', { }).then(() => {
next({ ...to, replace: true })
})
})
} else {
next()
NProgress.done()
}
}
} else {
if (to.path == '/login') { // 如果是登录页面路径,就直接next()
next()
NProgress.done()
} else { // 不然就跳转到登录;
next('/login')
}
}
})
GetUserInfo 仓库方法 获取存在缓存中的用户信息,然后再存在仓库里面
GetUserInfo ({ commit, state }) {
return new Promise((resolve, reject) => {
let userinfo = JSON.parse(getUser())
commit('SET_AVATAR', userinfo.Avatar)
commit('SET_NAME', userinfo.Name)
resolve()
})
},
GenerateRoutes这个是设置获取路由的方法
GenerateRoutes ({ commit }, data) {
return new Promise(resolve => {
// 获取缓存中的菜单信息
if (getModule()) {
let menu = JSON.parse(getModule())
let routers = []
generaMenu(routers, menu)
commit('SET_ROUTERS', routers)
resolve()
} else {
// 没有就请求接口 获取菜单接口
req.get('System/GetSysModule', {}).then(res => {
if (res.StatusCode === 200) {
// 设置缓存
setModule(JSON.stringify(res.Data))
let routers = []
generaMenu(routers, res.Data)
//
commit('SET_ROUTERS', routers)
resolve()
} else {
resolve()
}
})
}
})
}
generaMenu 这个方法 把后台返回的菜单组装成 路由的集合
function generaMenu (routers, data) {
data.forEach((item) => {
let menu = {
path: item.MUrl,
//这里的lazyLoading 可以替换成 () => import(`@/views${item.MUrl}`) 我这里是封装了一个方法
component: !item.MUrl ? Layout : lazyLoading(item.MUrl),
hidden: true,
children: [],
name: item.MUrl,
meta: {title: item.MName, icon: item.MIcon, id: item.ID}
}
if (item.Childrens) {
generaMenu(menu.children, item.Childrens)
}
routers.push(menu)
})
}
下面是permission.js 的完整代码
import { asyncRouterMap, constantRouterMap } from '@/router'
import { getModule, setModule } from '@/utils/auth'
import lazyLoading from '@/utils/lazyLoading'
import req from '@/utils/req'
import Layout from '@/views/Layout/index'
// import moudle from '@/views/system/moudle'
import router from '@/router'
function generaMenu (routers, data) {
data.forEach((item) => {
let menu = {
path: item.MUrl,
component: !item.MUrl ? Layout : lazyLoading(item.MUrl),
hidden: true,
children: [],
name: item.MUrl,
meta: {title: item.MName, icon: item.MIcon, id: item.ID}
}
if (item.Childrens) {
generaMenu(menu.children, item.Childrens)
}
routers.push(menu)
})
}
const permission = {
state: {
routers: constantRouterMap,
addRouters: []
},
mutations: {
SET_ROUTERS: (state, routers) => {
state.addRouters = routers
state.routers = constantRouterMap.concat(routers)
//这里将动态组装的路由添加到路由里面
router.addRoutes(state.routers)
}
},
actions: {
GenerateRoutes ({ commit }, data) {
return new Promise(resolve => {
// 获取缓存中的菜单信息
if (getModule()) {
let menu = JSON.parse(getModule())
let routers = []
generaMenu(routers, menu)
commit('SET_ROUTERS', routers)
resolve()
} else {
// 没有就请求接口 获取菜单接口
req.get('System/GetSysModule', {}).then(res => {
if (res.StatusCode === 200) {
// 设置缓存
setModule(JSON.stringify(res.Data))
let routers = []
generaMenu(routers, res.Data)
commit('SET_ROUTERS', routers)
resolve()
} else {
resolve()
}
})
}
})
}
}
}
export default permission
下面是 router 里面的代码
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
export const constantRouterMap = [
{
path: '/login',
component: () => import('@/views/login/index'),
hidden: true
}
]
export default new Router({
// mode: 'history', // require service support
scrollBehavior: () => ({ y: 0 }),
routes: constantRouterMap
})
export const asyncRouterMap = [
]
二、 找到仓库的存放的导航菜单信息,展示到左侧
写了一个公用的组件 NavMenu 在引用的时候获取 存在仓库里面的路由
<template>
<div class="navMenu " :class="isCollapse?'collapseY':'collapseN'">
<label v-for="(navMenu,index) in navMenus" :key="index">
<!-- <router-link :to="navMenu.entity.value"> -->
<el-menu-item v-if="navMenu.children.length==0&&navMenu.meta.id" @click="goRouter(navMenu.path)"
:key="navMenu.path" :data="navMenu" :index="navMenu.path"
>
<i :class="navMenu.meta.icon" style="margin-right:5px;"></i>
<span slot="title" >{{navMenu.meta.title}}</span>
</el-menu-item>
<!-- </router-link> -->
<el-submenu v-if="navMenu.children.length>0"
:key="navMenu.meta.id" :data="navMenu" :index="navMenu.path">
<!-- <router-link :to="navMenu.entity.value"> -->
<template slot="title" @click="goRouter(navMenu.path)">
<i :class="navMenu.meta.icon"></i>
<span> {{navMenu.meta.title}}</span>
</template>
<!-- </router-link> -->
<NavMenu :navMenus="navMenu.children" :isCollapse='isCollapse'></NavMenu>
</el-submenu>
</label>
</div>
</template>
然后 在一个写一个公用的layout 组件引用 ,
效果如下
结束语
可能写的不好,希望大神们反馈