11.后台管理系统之动态tabs制作
1. 第一步,先在侧边栏组件中绑定跳转事件
<template>
<el-menu background-color="#1d6a96" text-color="#fff" active-text-color="#66b1ff" :default-active="String(activeNav)">
<!-- 没有儿子的导航栏 -->
<el-menu-item :index="item.path" v-for="item in noChildren" :key="item.path" @click="clickMenu(item)">
<i :class="'el-icon-' + item.icon"></i>
<span slot="title">{{ item.label }}</span>
</el-menu-item>
<!-- 有儿子的导航栏 -->
<el-submenu index="index" v-for="(item, index) in hasChildren" :key="index">
<template slot="title">
<i :class="'el-icon-' + item.icon"></i>
<span>{{ item.label }}</span>
</template>
<el-menu-item-group>
<el-menu-item :index="subItem.path" v-for="(subItem, subIndex) in item.children" :key="subIndex" @click="clickMenu(subItem)">
<i :class="'el-icon-' + subItem.icon"></i>
<span slot="title">{{ subItem.label }}</span>
</el-menu-item>
</el-menu-item-group>
</el-submenu>
</el-menu>
</template>
<script>
export default {
data() {
return {
asideMenu: [
{
path: '/',
name: 'home',
label: '首页',
icon: 'info'
},
{
path: '/video',
name: 'video',
label: '视频管理页',
icon: 'video-play'
},
{
path: '/user',
name: 'user',
label: '用户管理页',
icon: 'user'
},
{
path: '/other',
name: 'other',
label: '其他',
icon: 'phone',
children: [
{
path: '/pageone',
name: 'pageone',
label: '其他1',
icon: 'phone'
},
{
path: '/pagetwo',
name: 'pagetwo',
label: '其他2',
icon: 'phone'
}
]
}
]
}
},
computed: {
// 设置当前激活的导航
activeNav() {
return this.$route.path
},
// 左侧导航栏无子节点
noChildren() {
return this.asideMenu.filter(item => !item.children)
},
// 左侧导航栏有子节点
hasChildren() {
return this.asideMenu.filter(item => item.children)
}
},
methods: {
clickMenu(item) {
this.$router.push({ name: item.name })
this.$store.commit('selectMenu', item)
}
}
}
</script>
<style lang="scss" scoped>
.el-menu {
height: 100%;
border: none;
}
</style>
2.在vuex状态管理中存储tabList
- 在
store
中新建tab
目录,再建tab.js
export default {
state: {
currentMenu: {}, // 左侧选择当前的路由
tabList: [
{
path: '/home',
name: 'home',
label: '首页',
icon: 'info'
}
] // tabs列表
},
mutations: {
selectMenu(state, val) {
if (val.name !== 'home') {
state.currentMenu = val
const result = state.tabList.findIndex(item => item.name === val.name)
if (result === -1) {
state.tabList.push(val)
}
} else {
state.currentMenu = null
}
},
closeTab(state, val) {
const result = state.tabList.findIndex(item => item.name === val.name)
state.tabList.splice(result, 1)
}
},
actions: {}
}
3.新建CommonTab.vue组件
- 在
components
下的common
目录下新建’CommonTab.vue`组件
<template>
<div class="common-tab">
<div class="tab-menu">
<el-tag
:key="tag.name"
v-for="tag in tags"
:closable="tag.name !== 'home'"
:disable-transitions="false"
@click="changeMenu(tag)"
@close="handleClose(tag)"
:effect="$route.name === tag.name ? 'dark' : 'plain'"
>
<i :class="'el-icon-' + tag.icon"></i>
{{ tag.label }}
</el-tag>
</div>
<div class="refresh-btn">
<el-button type="primary" icon="el-icon-refresh"></el-button>
</div>
</div>
</template>
<script>
import { mapState } from 'vuex'
export default {
data() {
return {}
},
computed: {
...mapState({
tags: state => state.tab.tabList
})
},
methods: {
// 点击切换页面方法
changeMenu(item) {
this.$router.push({ name: item.name })
this.$store.commit('selectMenu', item)
},
// 关闭界面的方法
handleClose(tag) {
this.$store.commit('closeTab', tag)
}
}
}
</script>
<style lang="scss" scoped>
// tabs容器
.common-tab {
display: flex;
justify-content: space-between;
}
// tabs按钮容器
.tab-menu {
flex: 1;
padding: 10px;
white-space: nowrap;
overflow-x: auto;
.el-tag {
margin-right: 15px;
cursor: pointer;
}
}
.refresh-btn {
padding: 10px;
}
/*滚动条样式*/
// 滚动条整体部分
.tab-menu::-webkit-scrollbar {
width: 4px;
height: 2px;
}
// 滚动条里面的小方块,能上下移动,取决于是垂直滚动还是水平滚动
.tab-menu::-webkit-scrollbar-thumb {
border-radius: 10px;
-webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
background: #498eaf;
}
// 滚动条的轨道
.tab-menu::-webkit-scrollbar-track {
-webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
border-radius: 0;
background: #fff;
}
</style>
4.将组件导入Main.vue中
<template>
<el-container style="height: 100%;">
<el-aside width="200px">
<common-aside></common-aside>
</el-aside>
<el-container>
<el-header style="background:#498eaf">
<common-header></common-header>
</el-header>
<common-tab></common-tab>
<el-main style="background:#fff;">
<router-view></router-view>
</el-main>
</el-container>
</el-container>
</template>
<script>
// 导入导航栏组件
import CommonAside from '@/components/common/CommonAside.vue'
// 导入首页头部组件
import CommonHeader from '@/components/common/CommonHeader.vue'
// 导入tabs组件
import CommonTab from '@/components/common/CommonTab.vue'
export default {
// 组件注册
components: {
CommonAside,
CommonHeader,
CommonTab
}
}
</script>
<style lang="scss" scoped></style>
5.效果展示
下一章描述一下tab的优化。