vue element 左侧动态树形导航 Demo
因为官方给的例子是死的数据,全都用html写出来很多,所以想通过数据去展示nav,于是简单踩了下坑。效果图code<div class="nav-list"><el-row class="tac"><el-col><el-menudefault-active="/"...
·
因为官方给的例子是死的数据,全都用html写出来很多,所以想通过数据去展示nav,于是简单踩了下坑。
第一种:折叠式 nav code
<template>
<el-container class="app-default-layout">
<el-aside class="app-left-nav bg-gredient-indigo" :style="{'max-width': drawer ? '70px' : '300px'}">
<el-menu
:default-active="activeIndex"
@select="handleSelect"
router
class="el-menu-vertical-nav color-white"
text-color="#FFFFFF"
active-text-color="#FFFFFF"
:background-color="drawer ? '#14191F' : 'transparent'"
:show-timeout="50"
:hide-timeout="50"
:collapse="drawer">
<template v-for="(subMenu, subIndex) in navList">
<!--只有一级菜单-->
<el-menu-item v-if="!subMenu.children" :key="subIndex" :index="subMenu.to">
<v-icon color="#FFFFFF" class="mr-1" v-html="subMenu.icon"></v-icon>
<span slot="title">{{ subMenu.title }}</span>
</el-menu-item>
<!-- 多级菜单 -->
<el-submenu v-else :index="subIndex + ''" :key="subIndex">
<template slot="title">
<i class="el-icon-location"></i>
<span>{{ subMenu.title }}</span>
</template>
<el-menu-item-group>
<span slot="title" v-show="drawer">{{ subMenu.title }}</span>
<template v-for="(menu, index) in subMenu.children">
<el-menu-item
v-if="(menu.title === 'Projects' && isAdminOrLTE) || menu.title !== 'Projects'"
:index="menu.to"
:key="index"
>
<v-icon color="#FFFFFF" class="mr-1" v-html="menu.icon"></v-icon>
{{ menu.title }}
</el-menu-item>
</template>
</el-menu-item-group>
</el-submenu>
</template>
</el-menu>
</el-aside>
<el-container class="app-container-box" :style="{'padding-left': drawer ? '70px' : '300px'}">
<el-header class="d-flex justify-space-between align-center app-header-nav" :style="{'left': drawer ? '70px' : '300px'}">
<el-button class="side-nav-btn header-nav-btn" :icon="drawer ? 'el-icon-s-unfold side-nav-icon' : 'el-icon-s-fold side-nav-icon'" circle @click="changeSideStatus()"></el-button>
<div class="d-flex justify-end align-center">
<v-icon style="max-width: 24px;" class="mr-2">account_circle</v-icon>
{{ $store.state.auth.user.user_name }}
<el-button class="logout-btn header-nav-btn ml-2" circle @click="logout()">
<v-icon>exit_to_app</v-icon>
</el-button>
</div>
</el-header>
<el-main class="bg-gredient-lightBlue" data-app="true" style="margin-top: 45px;">
<nuxt />
</el-main>
<el-footer style="height: 26px; padding-top: 3px;">
<p style="text-align: center;" class="mb-0">ARES © 2019</p>
</el-footer>
</el-container>
</el-container>
</template>
<script>
export default {
data () {
return {
drawer: false,
navList: [
{ icon: 'apps', title: 'Dashboard', to: '/' },
{ icon: 'description', title: 'BKMs', to: '/bkms' },
// { icon: 'date_range', title: 'Plans', to: '/plans', checkProject: true },
{ icon: 'date_range', title: 'Plans', to: '/plans' },
// { icon: 'event_note', title: 'Memo', to: '/memos', checkProject: true },
{ icon: 'assignment', title: 'Engineer', to: '/engineer' },
{ icon: 'assignment', title: 'HR', to: '/hr' },
{ icon: 'bug_report', title: 'Tracking', to: '/trackings' },
{ icon: 'view_list', title: 'Resources', to: '/resources' },
{ icon: 'event_note', title: 'Project', to: `/projects` },
// { icon: 'folder_open', title: 'FW', to: '/fws', checkProject: true }
{
icon: 'show_chart',
title: 'ARES Rept.',
children: [
{ icon: 'list_alt', title: 'Defects', to: '/defects' },
{ icon: 'list_alt', title: 'Defects Classification', to: '/defectsClassification' },
{ icon: 'storage', title: 'Projects', to: '/projectares' },
{ icon: 'poll', title: 'Defect Flight Pattern', to: '/defectFlightPattern' }
]
},
{
icon: 'account_circle',
title: 'Admin',
children: [
// { icon: 'event_note', title: 'Projects', to: '/projects' },
{ icon: 'view_agenda', title: 'Progress', to: '/progress' },
{ icon: 'people', title: 'Customers', to: '/customers' },
{ icon: 'assessment', title: 'Patterns', to: '/patterns' },
{ icon: 'face', title: 'Users', to: '/users' },
{ icon: 'local_offer', title: 'Tags', to: '/tags' },
{ icon: 'timeline', title: 'Timeline', to: '/timeline' },
{ icon: 'assignment', title: 'Resource Types', to: '/resourcetypes' },
{ icon: 'schedule', title: 'Schedule', to: '/schedule' }
]
}
],
activeIndex: '/'
}
},
watch: {
'$route' () {
this.handleSelect(this.activeIndex)
}
},
methods: {
changeSideStatus () {
this.drawer = !this.drawer
},
handleSelect (index) {
this.activeIndex = index
}
},
mounted () {
this.activeIndex = this.$route.matched[0].path || '/'
}
}
</script>
<style lang="stylus">
.app-default-layout {
min-width: 100vh;
.app-left-nav {
position: fixed;
left: 0;
top: 0;
bottom: 0;
z-index: 100;
overflow-x: hidden;
overflow-y: auto;
transition: all .1s;
}
.el-menu-vertical-nav {
width: 70px;
border: 0;
.el-menu-item:hover,
.el-submenu .el-submenu__title:hover {
background-color: hsla(0, 0%, 100%, .08) !important;
}
.el-menu-item.is-active {
background-color: hsla(0, 0%, 100%, .2) !important;
}
.el-menu-item-group__title {
padding-top: 0;
padding-bottom: 0;
}
}
.el-menu-vertical-nav:not(.el-menu--collapse) {
width: 300px;
}
.app-container-box {
transition: all .1s;
min-height: 100vh;
}
.app-header-nav {
position: fixed;
top: 0;
right: 0;
height: 45px !important;
z-index: 100;
background-color: #f5f5f5;
transition: all .1s;
box-shadow: 0 2px 4px -1px rgba(0,0,0,.2), 0 4px 5px 0 rgba(0,0,0,.14), 0 1px 10px 0 rgba(0,0,0,.12);
}
.header-nav-btn {
border: 0;
padding: 0;
background: transparent;
&:focus {
background: transparent;
color: #606266;
}
&:hover {
background: #DCDCDC;
color: #606266;
}
}
.side-nav-btn {
width: 35px;
height: 35px;
max-width: 35px;
i.side-nav-icon {
font-size: 26px;
}
}
.logout-btn {
width: 30px;
height: 30px;
max-width: 30px;
}
}
.el-menu--vertical {
.el-menu-item:hover {
background-color: hsla(0, 0%, 100%, .1) !important;
}
.el-menu-item.is-active {
background-color: hsla(0, 0%, 100%, .2) !important;
}
}
</style>
第二种:普通 nav 效果图
code
<div class="nav-list">
<el-row class="tac">
<el-col>
<el-menu
default-active="/"
router
class="el-menu-vertical-demo"
background-color="#545c64"
text-color="#fff"
active-text-color="#ffd04b"
>
<div v-for="(subMenu, subIndex) in navList" :key="subIndex">
<!--只有一级菜单-->
<el-menu-item v-if="!subMenu.children" :index="subMenu.to">
<i class="el-icon-location"></i>
{{ subMenu.title }}
</el-menu-item>
<!-- 多级菜单 -->
<el-submenu v-else :index="subIndex + ''">
<template slot="title">
<i class="el-icon-location"></i>
<span>{{ subMenu.title }}</span>
</template>
<el-menu-item-group>
<el-menu-item
v-for="(menu, index) in subMenu.children"
:index="menu.to"
:key="index"
>
<i class="el-icon-location"></i>
{{ menu.title }}
</el-menu-item>
</el-menu-item-group>
</el-submenu>
</div>
</el-menu>
</el-col>
</el-row>
</div>
js
data() {
return {
navList: [
{
icon: 'apps',
title: 'Index',
children: [
{
icon: 'apps',
title: 'page1',
to: '/ac'
},
{
icon: 'apps',
title: 'page2',
to: '/'
}
]
},
{ icon: 'assignment', title: 'BKMs', to: '/acb' },
{
icon: 'apps',
title: 'demo',
children: [
{
icon: 'apps',
title: 'demo1',
to: '/accb'
}
]
}
]
}
},
- 首先想让他变成路由导航,el-menu 一定要添加 router 属性,此时他就会根据 el-menu-item 中的 index 去 push router
- 需要注意的是:多级菜单时,虽然 el-submenu 并不想让他跳转,但是一定要加上 index 属性(可以放index就行,保证唯一性)
- index 属性的值一定要是 string ,比如 我的 subIndex 就要拼接个 ‘’ ,达到转换字符串的目的
- 我的 Demo 只有两层,如果需要更多层,继续嵌套就可以了。
觉得有帮助的小伙伴右上角点个赞~
扫描上方二维码关注我的订阅号~
更多推荐
已为社区贡献16条内容
所有评论(0)