点击左侧菜单栏,面包屑实时更新,如果所点击菜单在面包屑中存在,需要缓存,不存在重新加载,面包屑tab切换需要缓存,关闭one-tab更新tabslist。
keepalive只支持二级路由,多级路由需要扁平化处理。
使用vuex,vue-class-component类组件封装,自行转换。
面包屑tabs组件components/CommonTab.vue
<template>
<div class="tabs" ref="tags">
<el-tabs v-model="currentName" type="card" @edit="handleTabsEdit" @tab-click="handleTabClick">
<el-tab-pane :key="tag.name" v-for="tag in tags" :closable="tag.name === ('首页' || '首頁') ? false : true" :label="tag.meta.title" :name="tag.meta.title"> </el-tab-pane>
</el-tabs>
</div>
</template>
<script lang="ts">
import { Vue, Component, Mixins, Watch, Prop } from 'vue-property-decorator';
@Component
export default class CommonTab extends Vue {
tags: any = [];
editableTabsValue: any = '';
currentName: any = '';
async mounted() {
this.tags = this.$store.state.tabsList;
}
@Watch('$route.meta.title', { deep: true })
onTagsChange(newVal: any, oldVal: any) {
if (newVal !== oldVal) {
this.currentName = newVal;
}
}
handleTabsEdit(targetName: any, action: any) {
if (action === 'remove') {
// tags
let result = this.tags.findIndex((item: any) => item.meta.title === targetName);
this.handleClose(this.tags[result], result);
}
}
handleTabClick(tab: any) {
let result = this.tags.findIndex((item: any) => item.meta.title === this.currentName);
this.changeMenu(this.tags[result]);
}
handleClose(tag: any, index: any) {
let length = (this as any).tags.length - 1;
// vuex调方法的另一种写法
this.$store.commit('closeTab', tag);
// 如果关闭的标签不是当前路由的话,就不跳转
if (tag.name !== (this as any).$route.name) {
return;
}
// 关闭的标签是最右边的话,往左边跳转一个
if (index === length) {
(this as any).$router.push({ path: (this as any).tags[index - 1].path });
} else {
// 否则往右边跳转
(this as any).$router.push({ path: (this as any).tags[index].path });
}
}
// 选择标签跳转路由
changeMenu(item: any) {
(this as any).$router.push(item.path);
(this as any).$store.commit('selectMenu', item);
}
}
</script>
<style lang="scss" scope>
.tabs {
// line-height: 20px;
margin-left: 18px;
text-align: center;
position: relative;
}
.el-tabs {
color: #000;
border-radius: 17px;
// border: 1px solid red;
left: 0px;
top: 0px;
height: 32px;
position: relative;
}
.el-tabs__item {
// border: 1px solid red;
border-radius: 5px;
padding: 0 5px;
margin-left: 5px;
background: white;
line-height: 28px;
height: 28px;
font-size: 12px;
}
.el-tabs__nav-next,
.el-tabs__nav-prev {
line-height: 28px;
}
.el-tabs__item.is-active {
background: #409eff;
color: white !important;
padding-right: 5px !important;
padding-left: 5px !important;
}
</style>
vuex
import Vue from 'vue';
import Vuex from 'vuex';
let availButtons = new Set();
export default new Vuex.Store({
modules: {
// 把 store/modules下的文件引入
},
state: {
buttons: availButtons,
currentMenu: null,
menu: [],
tabsList: [
{
path: '/',
name: 'Profile',
icon: 'home',
meta: {
title: '首页'
}
}
],
keepAliveList: ['Profile']
},
mutations: {
// 选择标签 选择面包屑
selectMenu(state, val) {
console.log({ val });
if (val.path === '/') {
state.currentMenu = null;
} else {
state.currentMenu = val;
let result = state.tabsList.findIndex(item => item.name === val.name);
if (result === -1) {
state.tabsList.push(val);
}
}
},
closeTab(state, val) {
let result = state.tabsList.findIndex(item => item.name === val.name);
state.tabsList.splice(result, 1);
state.keepAliveList = [];
state.tabsList.forEach(item => {
state.keepAliveList.push(item.name);
});
},
updateKeepList(state, val) {
let index = state.keepAliveList.findIndex((item: any) => item.name === val.name);
if (index === -1) {
state.keepAliveList.push(val.name);
}
}
},
actions: {},
getters: {}
});
Home.vue(控制router-view的主页面)
<transition>
<keep-alive :include="$store.state.keepAliveList">
<router-view> </router-view>
</keep-alive>
</transition>
点击菜单触发事件:
在el-menu-item中@click
clickMenu(item: any) {
this.$store.commit('selectMenu', this.$route);
this.$store.commit('updateKeepList', this.$route);
}
route结构配置
{
path: '/login',
component: Login
},
{
path: '/',
component: Home,
children: [
{
name: 'profile',
path: '/',
component: Profile,
meta: {
title: '首页'
}
},
{
name: 'Users',
path: '/users',
component: Users,
meta: {
title: '用户管理'
}
},
{
name: 'Roles',
path: '/roles',
component: Roles,
meta: {
title: '角色管理'
}
}
]}
缺点:默认刷新之后进入Profile页面,没有动态更新刷新。可以在Home中mouted中自定义传值当前router。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)