面包屑 + Tag标签切换功能
有关后台管理系统以前写过两遍博客,看这篇以前最好先看下这两篇博客。另外这里只展现关键部分代码,项目代码放在github上: mall-manage-systemjavascript
一、Vue + Element-ui实现后台管理系统(1) --- 总述html
二、Vue + Element-ui实现后台管理系统(2)---项目搭建 + ⾸⻚布局实现vue
这篇主要讲解 面包屑 + Tag标签切换功能:java
总体效果
git


说明
从上面图片能够看出,面包屑是在head部分组件里,Tag标签虽然再也不head部分组件里,可是它在整个管理后台系统中是会一直存在的,因此须要在Main.vue中。github
这两块功能的实现,主要依赖Element-ui两个样式 Breadcrumb 面包屑 + Tag 标签vuex
1、面包屑功能
一、背景
整个大体逻辑是这样的,首先是面包屑 首页
必定要存在的,接下来 侧边组件 点击某菜单,把这个数据存到vuex中,而后 头部组件 来获取vuex中这个数据并展现。ide
二、CommonAside(侧边栏)
侧边栏须要作的就是当click当前菜单 就要把这个数据存储到vuex中,为了头部组件来获取展现这份数据。布局
这里定义了一个click事件ui
methods: { //跳转路由 根据名称跳转 clickMenu(item) { //调用vuex的selectMenu方法存储数据 this.$store.commit('selectMenu', item) //跳转路由 this.$router.push({ name: item.name }) } }
三、CommonHeader(头部组件)
由于面包屑是写在CommonHeader中,因此这里展现这部分代码
<el-breadcrumb separator-class="el-icon-arrow-right"> <!--很明显 首页 必定是存在的 因此这里直接写死--> <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item> <!--第二级菜单名称 就要看左侧组件有没有点击指定菜单,没有那就只显示首页 点击就显示当前菜单名称--> <el-breadcrumb-item :to="current.path" v-if="current" >{{current.label}}</el-breadcrumb-item> </el-breadcrumb> <script> //js部分 import { mapState } from 'vuex' export default { computed: { //获取vuex数据的另外一种写法 ...mapState({ current: state => state.tab.currentMenu }) } } </script>
四、vuex配置
这里用了一个属性为 currentMenu 的来存储当前菜单信息
state: { //当前菜单 currentMenu: null, }, mutations: { selectMenu(state, val) { //若是点击应该是首页的话 要把这份数据清空 由于头部组件已经把首页写死了 只有点击不是首页菜单才存储当前菜单 val.name === 'home' ? (state.currentMenu = null) : (state.currentMenu = val) } }, }
这样整个面包屑的功能就是实现了。
2、Tag标签切换功能

一、背景
从上面效果来看,咱们发现:
一、首页的tag一开始就会存在,并且是不能进行删除的 二、当点击左侧栏的时候,若是tag没有该菜单名称则新增,若是已经有了那么当前tag背景为蓝色。 三、删除当前tag,若是是最后一个,那么路由调整到它前面那个标签而且背景变蓝,若是不是最后一个那么路由调整到它后面那个标签而且背景变蓝。 四、还有咱们注意这个tag不论路由如何切换都是会存在的,因此这个tag必定要存在咱们以前定义的Main.vue中。
二、CommonTab.vue(标签组件)
<template> <div class="tabs"> <!--closable这里说明home是不能关闭的--> <el-tag :key="tag.name" size="small" v-for="(tag, index) in tags" :closable="tag.name !== 'home'" :disable-transitions="false" @close="handleClose(tag, index)" @click="changeMenu(tag)" :effect="$route.name === tag.name ? 'dark' : 'plain'" > {{ tag.label }} </el-tag> </div> </template> <script> import { mapState, mapMutations } from 'vuex' export default { computed: { //获取vuex的标签集合数据 ...mapState({ tags: state => state.tab.tabsList }) }, methods: { ...mapMutations({ close: 'closeTab' }), //关闭标签 handleClose(tag, index) { let length = this.tags.length - 1 //vuex调方法的另外一种写法 this.close(tag) // 若是关闭的标签不是当前路由的话,就不跳转 if (tag.name !== this.$route.name) { return } // 关闭的标签是最右边的话,往左边跳转一个 if (index === length) { this.$router.push({ name: this.tags[index - 1].name }) } else { // 不然往右边跳转 this.$router.push({ name: this.tags[index].name }) } }, //选择标签跳转路由 changeMenu(item) { this.$router.push({ name: item.name }) this.$store.commit('selectMenu', item) } } } </script>
三、vuex配置
export default { //存储数据 state: { currentMenu: null, tabsList: [ { path: '/', name: 'home', label: '首页', icon: 'home' } ] }, //调用方法 mutations: { //选择标签 选择面包屑 selectMenu(state, val) { if (val.name === 'home') { state.currentMenu = null } else { state.currentMenu = val //若是等于-1说明tabsList不存在那么插入,不然什么都不作 let result = state.tabsList.findIndex(item => item.name === val.name) result === -1 ? state.tabsList.push(val) : '' } // val.name === 'home' ? (state.currentMenu = null) : (state.currentMenu = val) }, //关闭标签 closeTab(state, val) { let result = state.tabsList.findIndex(item => item.name === val.name) state.tabsList.splice(result, 1) }, }, actions: {} }
四、Main.vue(主组件)
既然tag在整个后台都要显示,那么就须要将CommonTab.vue加入到Main.vue中。
<template> <el-container style="height: 100%"> <el-aside width="auto"> <common-aside></common-aside> </el-aside> <el-container> <el-header> <common-header></common-header> </el-header> <!--加入CommonTab--> <common-tab></common-tab> <el-main> <router-view/> </el-main> </el-container> </el-container> </template>
具体的看完整项目吧,最上面已经给了github地址了。
别人骂我胖,我会生气,由于我内心认可了我胖。别人说我矮,我就会以为可笑,由于我内心知道我不可能矮。这就是咱们为何会对别人的攻击生气。 攻我盾者,乃我心里之矛(14)