elementui 搭建布局页面路由_vue+elementui搭建后台管理界面(5递归生成侧栏路由)

有一个菜单树,顶层菜单下面有多个子菜单,子菜单下还有子菜单。。。

这时候就要用递归处理

1 定义多级菜单

修改 src/router/index.js 的 / 路由

{

path: '/',

redirect: '/dashboard',

name: 'Container',

component: Container,

children: [

{path: 'dashboard', name: '首页', component: Dashboard,

children: [

{path: 'dashboard1', name: '首页1', component: Dashboard,},

{path: 'dashboard2', name: '首页2', component: Dashboard,

children: [

{path: 'dashboard21', name: '首页21', component: Dashboard,},

{path: 'dashboard22', name: '首页22', component: Dashboard, },

] },

]

},

{path: 'article', name: '文章', component: Article, },

]

}

2 抽出Sidebar组件

生成的递归路由放在侧边栏,因此抽取 sidebar 组件,sidebar 包含logo和 递归路由

再抽取 SidebarItem 为单独的路由组件,方便递归调用

2.1 Sidebar

Sidebar 接收collapse、路由数组,同时引入 SidebarItem 组件

子组件传入:

barIdx: 当前路由的索引,用来定位子菜单

subroute: 路由对象

fatherpath: 父路径,如 /、 /a/b

:default-active="defaultActive"

router

:collapse="collapse"

>

:subroute="item"

:fatherpath="fatherPath"

:barIdx="idx" :key="idx" />

import SidebarItem from './SidebarItem'

export default {

naem: "Sidebar",

components: {

SidebarItem

},

props: {

collapse: {

type: Boolean

},

routes: {

type: Array

}

},

computed: {

// 首次进入页面时展开当前页面所属的菜单

defaultActive(){

return this.$route.path

},

fatherPath(){

// 这里直接获取路由配置的 '/' 项

return this.$router.options.routes[1].path

}

}

}

2.2 SidebarItem

SidebarItem 接收路由、父路由path、父级idx,然后递归调用自身

:index="genPath(fatherpath, subroute.path)">

{{subroute.name}}

:subroute="submenu"

:fatherpath="genPath(fatherpath, subroute.path)"

:barIdx="subidx"

:key="barIdx + '-' + subidx"

/>

v-else-if="!subroute.hidden"

:index="genPath(fatherpath, subroute.path)"

>{{subroute.name}}

v-else

:index="genPath(fatherpath, subroute.path)"

>{{ subroute.name }}

export default {

name: 'SidebarItem',

props: {

subroute: {

type: Object

},

barIdx: {

type: [String, Number]

},

fatherpath: {

type: String

}

},

computed: {

// 默认激活的路由, 用来激活菜单选中状态

defaultActive: function(){

return this.$route.path

},

},

methods: {

// 生成侧边栏路由,格式: /a/b/c

genPath: function(){

let arr = [ ...arguments ]

let path = arr.map(v => {

while (v[0] === '/'){

v = v.substring(1)

}

while(v[-1] === '/'){

v = v.substring(0, v.length)

}

return v

}).join('/')

path = path[0] === '/' ? path : '/'+path

return path

},

handleOpen: function(key, keyPath) {

console.log(key, keyPath)

},

handleClose: function(key, keyPath) {

console.log(key, keyPath)

}

},

mounted: function(){

console.log('sidebar routes: ', this.routes)

}

}

3 项目结构

此时 src 的目录结构

│ App.vue

│ main.js

├─assets

│ logo.png

├─components

│ HelloWorld.vue

│ Sidebar.vue

│ SidebarItem.vue

├─container

│ Container.vue

├─router

│ index.js

├─styles

│ index.scss

└─views

│ TheLogin.vue

├─article

│ index.vue

└─dashboard

index.vue

4 修改容器配置

src/container/Container.vue 引入 Sidebar 组件

:class="isCollapse ? 'app-side-collapsed' : 'app-side-expanded'">

import Sidebar from '@/components/Sidebar'

export default {

name: 'Container',

components: {

Sidebar

},

/** ... */

页面效果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值