如何拍平多級選單
阿新 • • 發佈:2021-02-04
技術標籤:keep-alivekeep-alive無法快取多級選單vueelementuijavascript
如何拍平多級選單
兩步
關於keep-alive無法快取多級選單的解決,之前使用老版本的若依框架,無法做到多級選單之間切換的一個快取,這裡三步聊聊如何把多級選單拍平成為一級選單
一、處理後臺資料
1.—vuex —permission.js
在vuex拿到後臺路由資料的時候進行拍平。拿到的是一個有children的多級陣列,我們遍歷成一個單級的陣列然後addroutes到路由中。但是顯示在側邊欄的依然時多級陣列。完成這一步,應該可以通過路徑訪問到頁面了,就像訪問靜態路由一樣。程式碼如下:
GenerateRoutes({state, commit }) { return new Promise(resolve => { // 向後端請求路由資料 getRouters().then(res => { const sdata = JSON.parse(JSON.stringify(res.data)) const rdata = JSON.parse(JSON.stringify(res.data)) const sidebarRoutes = filterAsyncRouter(sdata) const rewriteRoutes = filterAsyncRouter(rdata, true) rewriteRoutes.push({ path: '*', redirect: '/404', hidden: true }) commit('SET_ROUTES', rewriteRoutes) commit('SET_SIDEBAR_ROUTERS', sidebarRoutes) //這裡的資料用於展示 let newList=[] deepOpen(rewriteRoutes,newList) //console.log(rewriteRoutes); resolve(newList) //返回一級路由陣列 }) }) } //拍平一級路由的方法 function deepOpen(list,newList){ list.forEach(item => { if(!item.children){ newList.push( { path: '/'+item.path, component: Layout, hidden: true, children: [ { path: item.path, component: item.component, name: item.name, meta: item.meta, } ] }, ) }else{ deepOpen(item.children,newList) } }); }
二、處理路徑
—layout —Sidebar --SidebarItem.vue
在佈局檔案的側邊欄中,修改路徑為我們之前設定的路徑,要一模一樣就ok了,之前設定的是path接上子元件的path所以是兩個path /path/path
這裡直接上這個元件全部檔案程式碼
<template> <div v-if="!item.hidden"> <template v-if="hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow"> <app-link v-if="onlyOneChild.meta" :to="resolvePath(item.path)"> <el-menu-item :index="'/'+item.path+'/'+item.path" :class="{'submenu-title-noDropdown':!isNest}"> <item :icon="onlyOneChild.meta.icon||(item.meta&&item.meta.icon)" :title="onlyOneChild.meta.title" /> </el-menu-item> </app-link> </template> <el-submenu v-else ref="subMenu" :index="resolvePath(item.path)" popper-append-to-body> <template slot="title"> <item v-if="item.meta" :icon="item.meta && item.meta.icon" :title="item.meta.title" /> </template> <sidebar-item v-for="child in item.children" :key="child.path" :is-nest="true" :item="child" :base-path="resolvePath(child.path)" class="nest-menu" /> </el-submenu> </div> </template> <script> import path from 'path' import { isExternal } from '@/utils/validate' import Item from './Item' import AppLink from './Link' import FixiOSBug from './FixiOSBug' export default { name: 'SidebarItem', components: { Item, AppLink }, mixins: [FixiOSBug], props: { // route object item: { type: Object, required: true }, isNest: { type: Boolean, default: false }, basePath: { type: String, default: '' } }, data() { this.onlyOneChild = null return {} }, methods: { hasOneShowingChild(children = [], parent) { const showingChildren = children.filter(item => { if (item.hidden) { return false } else { // Temp set(will be used if only has one showing child) this.onlyOneChild = item return true } }) // When there is only one child router, the child router is displayed by default if (showingChildren.length === 1) { return true } // Show parent if there are no child router to display if (showingChildren.length === 0) { this.onlyOneChild = { ... parent, path: '', noShowingChildren: true } return true } return false }, resolvePath(routePath) { //console.log(routePath); //return routePath // if (isExternal(routePath)) { // console.log(1); // return routePath // } // if (isExternal(this.basePath)) { // console.log(2); // return this.basePath // } // return path.resolve(this.basePath, routePath) // /console.log(routePath); return routePath } } } </script>
重點是resolvePath方法 注意一下傳的引數 這裡用的是item.path
還有就是applink元件的跳轉路徑也處理一下,當然我的路徑是在這邊處理的,你可以直接在上一個元件修改
linkProps(to) {
if (this.isExternal) {
return {
href: '/'+to+'/'+to,
target: '_blank',
rel: 'noopener'
}
}if(!to){
return {
to: '/'
}
}
return {
to: '/'+to+'/'+to
}
},
注意:如果修改完側邊欄的active顏色要點兩下才高亮的話,是因為那個default-active的值和el-menu-item的index不一致,改成一樣就可以了
這邊參考下中間那塊程式碼塊的
:index="’/’+item.path+’/’+item.path"