Vue 動態(tài)添加路由及生成菜單的方法示例
寫后臺管理系統(tǒng),估計有不少人遇過這樣的需求:根據(jù)后臺數(shù)據(jù)動態(tài)添加路由和菜單。
為什么這么做呢?因為不同的用戶有不同的權(quán)限,能訪問的頁面是不一樣的。
在網(wǎng)上找了好多資料,終于想到了解決辦法。
動態(tài)生成路由
利用 vue-router 的 addRoutes 方法可以動態(tài)添加路由。
先看一下官方介紹:
router.addRoutes
router.addRoutes(routes: Array<RouteConfig>)
動態(tài)添加更多的路由規(guī)則。參數(shù)必須是一個符合 routes 選項要求的數(shù)組。
舉個例子:
const router = new Router({
routes: [
{
path: '/login',
name: 'login',
component: () => import('../components/Login.vue')
},
{path: '/', redirect: '/home'},
]
})
上面的代碼和下面的代碼效果是一樣的
const router = new Router({
routes: [
{path: '/', redirect: '/home'},
]
})
router.addRoutes([
{
path: '/login',
name: 'login',
component: () => import('../components/Login.vue')
}
])
在動態(tài)添加路由的過程中,如果有 404 頁面,一定要放在最后添加,否則在登陸的時候添加完頁面會重定向到 404 頁面。
類似于這樣,這種規(guī)則一定要最后添加。
{path: '*', redirect: '/404'}
動態(tài)生成菜單
假設后臺返回來的數(shù)據(jù)長這樣
// 左側(cè)菜單欄數(shù)據(jù)
menuItems: [
{
name: 'home', // 要跳轉(zhuǎn)的路由名稱 不是路徑
size: 18, // icon大小
type: 'md-home', // icon類型
text: '主頁' // 文本內(nèi)容
},
{
text: '二級菜單',
type: 'ios-paper',
children: [
{
type: 'ios-grid',
name: 't1',
text: '表格'
},
{
text: '三級菜單',
type: 'ios-paper',
children: [
{
type: 'ios-notifications-outline',
name: 'msg',
text: '查看消息'
},
{
type: 'md-lock',
name: 'password',
text: '修改密碼'
},
{
type: 'md-person',
name: 'userinfo',
text: '基本資料',
}
]
}
]
}
]
來看看怎么將它轉(zhuǎn)化為菜單欄,我在這里使用了 iview 的組件,不用重復造輪子。
<!-- 菜單欄 -->
<Menu ref="asideMenu" theme="dark" width="100%" @on-select="gotoPage"
accordion :open-names="openMenus" :active-name="currentPage" @on-open-change="menuChange">
<!-- 動態(tài)菜單 -->
<div v-for="(item, index) in menuItems" :key="index">
<Submenu v-if="item.children" :name="index">
<template slot="title">
<Icon :size="item.size" :type="item.type"/>
<span v-show="isShowAsideTitle">{{item.text}}</span>
</template>
<div v-for="(subItem, i) in item.children" :key="index + i">
<Submenu v-if="subItem.children" :name="index + '-' + i">
<template slot="title">
<Icon :size="subItem.size" :type="subItem.type"/>
<span v-show="isShowAsideTitle">{{subItem.text}}</span>
</template>
<MenuItem class="menu-level-3" v-for="(threeItem, k) in subItem.children" :name="threeItem.name" :key="index + i + k">
<Icon :size="threeItem.size" :type="threeItem.type"/>
<span v-show="isShowAsideTitle">{{threeItem.text}}</span>
</MenuItem>
</Submenu>
<MenuItem v-else v-show="isShowAsideTitle" :name="subItem.name">
<Icon :size="subItem.size" :type="subItem.type"/>
<span v-show="isShowAsideTitle">{{subItem.text}}</span>
</MenuItem>
</div>
</Submenu>
<MenuItem v-else :name="item.name">
<Icon :size="item.size" :type="item.type" />
<span v-show="isShowAsideTitle">{{item.text}}</span>
</MenuItem>
</div>
</Menu>
代碼不用看得太仔細,理解原理即可,其實就是通過三次 v-for 不停的對子數(shù)組進行循環(huán),生成三級菜單。
動態(tài)菜單這樣就可以實現(xiàn)了。
動態(tài)路由,因為上面已經(jīng)說過了用 addRoutes 來實現(xiàn),現(xiàn)在看看具體怎么做。
首先,要把項目所有的頁面路由都列出來,再用后臺返回來的數(shù)據(jù)動態(tài)匹配,能匹配上的就把路由加上,不能匹配上的就不加。
最后把這個新生成的路由數(shù)據(jù)用 addRoutes 添加到路由表里。
const asyncRoutes = {
'home': {
path: 'home',
name: 'home',
component: () => import('../views/Home.vue')
},
't1': {
path: 't1',
name: 't1',
component: () => import('../views/T1.vue')
},
'password': {
path: 'password',
name: 'password',
component: () => import('../views/Password.vue')
},
'msg': {
path: 'msg',
name: 'msg',
component: () => import('../views/Msg.vue')
},
'userinfo': {
path: 'userinfo',
name: 'userinfo',
component: () => import('../views/UserInfo.vue')
}
}
// 傳入后臺數(shù)據(jù) 生成路由表
menusToRoutes(menusData)
// 將菜單信息轉(zhuǎn)成對應的路由信息 動態(tài)添加
function menusToRoutes(data) {
const result = []
const children = []
result.push({
path: '/',
component: () => import('../components/Index.vue'),
children,
})
data.forEach(item => {
generateRoutes(children, item)
})
children.push({
path: 'error',
name: 'error',
component: () => import('../components/Error.vue')
})
// 最后添加404頁面 否則會在登陸成功后跳到404頁面
result.push(
{path: '*', redirect: '/error'},
)
return result
}
function generateRoutes(children, item) {
if (item.name) {
children.push(asyncRoutes[item.name])
} else if (item.children) {
item.children.forEach(e => {
generateRoutes(children, e)
})
}
}
所有的代碼實現(xiàn),我都放在 github 上,動態(tài)菜單的實現(xiàn)放在這個項目下的 src/components/Index.vue、src/permission.js 和 src/utils/index.js下
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
使用vue-router切換頁面時實現(xiàn)設置過渡動畫
今天小編就為大家分享一篇使用vue-router切換頁面時實現(xiàn)設置過渡動畫。具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-10-10
Vue3之父子組件異步props數(shù)據(jù)的傳值方式
這篇文章主要介紹了Vue3之父子組件異步props數(shù)據(jù)的傳值方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2025-04-04
vue3.0使用taro-ui-vue3引入組件不生效的問題及解決
這篇文章主要介紹了vue3.0使用taro-ui-vue3引入組件不生效的解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-03-03

