vue-admin-template 动态路由的实现(方式二 推荐)

const newRouter = createRouter()

router.matcher = newRouter.matcher // reset router

}

export default router

将动态显示的路由写在asyncRoutes 中并添加 roles ,例如meta: { roles: [‘admin’] },

  • 在store/modulds目录下添加permission.js

在这里插入图片描述

import { asyncRoutes, constantRoutes } from ‘@/router’

/**

  • Use meta.role to determine if the current user has permission

  • @param roles

  • @param route

*/

function hasPermission(roles, route) {

if (route.meta && route.meta.roles) {

return roles.some(role => route.meta.roles.includes(role))

} else {

return true

}

}

/**

  • Filter asynchronous routing tables by recursion

  • @param routes asyncRoutes

  • @param roles

*/

export function filterAsyncRoutes(routes, roles) {

const res = []

routes.forEach(route => {

const tmp = { …route }

if (hasPermission(roles, tmp)) {

if (tmp.children) {

tmp.children = filterAsyncRoutes(tmp.children, roles)

}

res.push(tmp)

}

})

return res

}

const state = {

routes: [],

addRoutes: []

}

const mutations = {

SET_ROUTES: (state, routes) => {

state.addRoutes = routes

state.routes = constantRoutes.concat(routes)

}

}

const actions = {

generateRoutes({ commit }, roles) {

return new Promise(resolve => {

const accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)

commit(‘SET_ROUTES’, accessedRoutes)

resolve(accessedRoutes)

})

}

}

export default {

namespaced: true,

state,

mutations,

actions

}

  • 修改store/modulds/user.js

import { login, logout, getInfo } from ‘@/api/user’

import { getToken, setToken, removeToken } from ‘@/utils/auth’

import { resetRouter } from ‘@/router’

const getDefaultState = () => {

return {

token: getToken(),

name: ‘’,

avatar: ‘’,

roles: []

}

}

const state = getDefaultState()

const mutations = {

RESET_STATE: (state) => {

Object.assign(state, getDefaultState())

},

SET_TOKEN: (state, token) => {

state.token = token

},

SET_NAME: (state, name) => {

state.name = name

},

SET_AVATAR: (state, avatar) => {

state.avatar = avatar

},

SET_ROLES: (state, roles) => {

state.roles = roles

}

}

const actions = {

// user login

login({ commit }, userInfo) {

const { username, password } = userInfo

return new Promise((resolve, reject) => {

login({ username: username.trim(), password: password }).then(response => {

const { data } = response

commit(‘SET_TOKEN’, data.token)

setToken(data.token)

resolve()

}).catch(error => {

reject(error)

})

})

},

// get user info

getInfo({ commit, state }) {

return new Promise((resolve, reject) => {

getInfo(state.token).then(response => {

const { data } = response

if (!data) {

return reject(‘验证失败,请重新登录’)

}

const {roles, name, avatar } = data

commit(‘SET_ROLES’, roles)

commit(‘SET_NAME’, name)

commit(‘SET_AVATAR’, avatar)

resolve(data)

}).catch(error => {

reject(error)

})

})

},

// user logout

logout({ commit, state }) {

return new Promise((resolve, reject) => {

logout(state.token).then(() => {

removeToken() // must remove token first

resetRouter()

commit(‘RESET_STATE’)

commit(‘SET_ROLES’, [])

resolve()

}).catch(error => {

reject(error)

})

})

},

// remove token

resetToken({ commit }) {

return new Promise(resolve => {

removeToken() // must remove token first

commit(‘RESET_STATE’)

commit(‘SET_ROLES’, [])

resolve()

})

}

}

export default {

namespaced: true,

state,

mutations,

actions

}

添加roles: [] 保存权限列表 ,添加内容如下

const getDefaultState = () => {

return {

roles: []

}

}

const mutations = {

SET_ROLES: (state, roles) => {

state.roles = roles

}

}

// get user info

getInfo({ commit, state }) {

return new Promise((resolve, reject) => {

getInfo(state.token).then(response => {

const {roles, name, avatar } = data

commit(‘SET_ROLES’, roles)

}).catch(error => {

reject(error)

})

})

},

// user logout

logout({ commit, state }) {

return new Promise((resolve, reject) => {

logout(state.token).then(() => {

commit(‘SET_ROLES’, [])

}).catch(error => {

reject(error)

})

})

},

// remove token

resetToken({ commit }) {

return new Promise(resolve => {

commit(‘SET_ROLES’, [])

})

}

}

  • 在store/getters.js中添加roles

const getters = {

sidebar: state => state.app.sidebar,

device: state => state.app.device,

token: state => state.user.token,

avatar: state => state.user.avatar,

name: state => state.user.name,

//添加roles

roles: state => state.user.roles,

//动态路由

permission_routes: state => state.permission.routes,

}

export default getters

  • 将permission添加到store/index.js中

import Vue from ‘vue’

import Vuex from ‘vuex’

import getters from ‘./getters’

import app from ‘./modules/app’

import settings from ‘./modules/settings’

import user from ‘./modules/user’

//添加permission

import permission from ‘./modules/permission’

Vue.use(Vuex)

const store = new Vuex.Store({

modules: {

app,

settings,

user,

//添加permission

permission

},

getters

})

export default store

  • 最后修改根目录下的permission.js

import router, { constantRoutes } from ‘./router’

import store from ‘./store’

import { Message } from ‘element-ui’

import NProgress from ‘nprogress’ // progress bar

import ‘nprogress/nprogress.css’ // progress bar style

import { getToken } from ‘@/utils/auth’ // get token from cookie

import getPageTitle from ‘@/utils/get-page-title’

NProgress.configure({ showSpinner: false }) // NProgress Configuration

const whiteList = [‘/login’] // no redirect whitelist

router.beforeEach(async (to, from, next) => {

// start progress bar

NProgress.start()

// set page title

document.title = getPageTitle(to.meta.title)

// determine whether the user has logged in

const hasToken = getToken()

if (hasToken) {

if (to.path === ‘/login’) {

// if is logged in, redirect to the home page

next({ path: ‘/’ })

NProgress.done()

} else {

const hasRoles = store.getters.roles && store.getters.roles.length > 0

if (hasRoles) {

next()

} else {

try {

// get user info

// note: roles must be a object array! such as: [‘admin’] or ,[‘developer’,‘editor’]

const { roles } = await store.dispatch(‘user/getInfo’)

console.log(roles)

// generate accessible routes map based on roles

const accessRoutes = await store.dispatch(‘permission/generateRoutes’, roles)

// dynamically add accessible routes

router.options.routes = constantRoutes.concat(accessRoutes)

router.addRoutes(accessRoutes)

// hack method to ensure that addRoutes is complete

// set the replace: true, so the navigation will not leave a history record

next({ …to, replace: true })

} catch (error) {

// remove token and go to login page to re-login

await store.dispatch(‘user/resetToken’)

Message.error(error || ‘Has Error’)

next(/login?redirect=${to.path})

NProgress.done()

}

}

}

} else {

/* has no token*/

if (whiteList.indexOf(to.path) !== -1) {

// in the free login whitelist, go directly

next()

} else {

// other pages that do not have permission to access are redirected to the login page.

next(/login?redirect=${to.path})

NProgress.done()

}

}

})

router.afterEach(() => {

// finish progress bar

NProgress.done()

})

  • 将数据绑定到nav导航栏上

在layout/components/sidebar/index.vue中

…mapGetters([

// 动态路由 增加permission_routes

‘permission_routes’,

‘sidebar’

]),

全部代码如下:

<el-menu

:default-active=“activeMenu”

:collapse=“isCollapse”

:background-color=“variables.menuBg”

:text-color=“variables.menuText”

:unique-opened=“false”

:active-text-color=“variables.menuActiveText”

:collapse-transition=“false”

mode=“vertical”

<sidebar-item

v-for=“route in permission_routes”

:key=“route.path”

:item=“route”

:base-path=“route.path”

/>

  • 22
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
动态路由是指路由表在运行时动态生成,而不是在编译时生成。在 Vue.js 中,可以使用 Vue Router 实现动态路由。下面是一个简单的步骤,可以帮助你搭建一个基于 Vue-admin-template动态路由。 1. 安装 Vue Router ```bash npm install vue-router --save ``` 2. 在 src/router/index.js 中引入 Vue Router,并创建一个路由实例 ```javascript import Vue from 'vue'; import Router from 'vue-router'; import Layout from '@/layout'; Vue.use(Router); 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: 'Dashboard', icon: 'dashboard' } }] } ]; const createRouter = () => new Router({ mode: 'history', // 启用 history 模式 scrollBehavior: () => ({ y: 0 }), routes: constantRoutes }); const router = createRouter(); export default router; ``` 3. 在 src/store/modules/permission.js 中创建一个动态路由生成函数 ```javascript import { constantRoutes } from '@/router'; /** * 递归过滤异步路由表,返回符合用户角色权限的路由表 * @param routes asyncRoutes * @param roles */ export function filterAsyncRoutes(routes, roles) { const res = []; routes.forEach(route => { const tmp = { ...route }; if (hasPermission(roles, tmp)) { if (tmp.children) { tmp.children = filterAsyncRoutes(tmp.children, roles); } res.push(tmp); } }); return res; } /** * 判断用户角色是否有权限访问该路由 * @param roles * @param route */ function hasPermission(roles, route) { if (route.meta && route.meta.roles) { return roles.some(role => route.meta.roles.includes(role)); } else { return true; } } const state = { routes: [], addRoutes: [] }; const mutations = { SET_ROUTES: (state, routes) => { state.addRoutes = routes; state.routes = constantRoutes.concat(routes); } }; const actions = { generateRoutes({ commit }, roles) { return new Promise(resolve => { let accessedRoutes; if (roles.includes('admin')) { accessedRoutes = asyncRoutes || []; } else { accessedRoutes = filterAsyncRoutes(asyncRoutes, roles); } commit('SET_ROUTES', accessedRoutes); resolve(accessedRoutes); }); } }; export default { namespaced: true, state, mutations, actions }; ``` 4. 在 src/router/index.js 中引入动态路由生成函数,并在路由实例中使用 ```javascript import Vue from 'vue'; import Router from 'vue-router'; import Layout from '@/layout'; import store from '@/store'; Vue.use(Router); 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: 'Dashboard', icon: 'dashboard' } }] } ]; const createRouter = () => new Router({ mode: 'history', // 启用 history 模式 scrollBehavior: () => ({ y: 0 }), routes: constantRoutes }); const router = createRouter(); // 刷新页面时重新生成动态路由 router.beforeEach(async(to, from, next) => { const hasRoles = store.getters.roles && store.getters.roles.length > 0; if (hasRoles) { next(); } else { try { // 获取用户角色信息 const { roles } = await store.dispatch('user/getInfo'); // 生成动态路由 const accessedRoutes = await store.dispatch('permission/generateRoutes', roles); // 添加动态路由 router.addRoutes(accessedRoutes); next({ ...to, replace: true }); } catch (error) { console.log(error); } } }); export function resetRouter() { const newRouter = createRouter(); router.matcher = newRouter.matcher; // reset router } export default router; ``` 以上是一个基于 Vue-admin-template动态路由搭建步骤,你可以根据自己的需求进行修改和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值