涉及知识点:vuex,mixins,keepalive,route,computed,watch
1./store/index.js :
store:
keepAliveList:[],
mutations: setKeepAliveLists(state,keepName){ state.keepAliveList.push(keepName); }, removeKeepAliveItem(state,keepName){ state.keepAliveList.splice(state.keepAliveList.indexOf(keepName), 1) },
2./components/TopWatch :(非左侧标签导航组件,点击路由切换,可关闭)
监听路由变化,当其meta.keepAlive为true时将该路由的name存入keepAliveList this.$store.commit('setKeepAliveLists',storeCache);
点击关闭标签时,当其meta.keepAlive为true时将该路由的name存入keepAliveList this.$store.commit('removeKeepAliveItem',storeCache);
3.引入mixins在需要动态销毁的组件里,监听store.state.keepAliveList
import mixin from '../../mixin' export default { mixins:[mixin], }
4.当mixins所在组件的name不存在于store.state.keepAliveList时,执行this.$destroy()
export default {
computed: {
keepAliveConf(){
return this.$store.state.keepAliveList;
}
},
watch:{
keepAliveConf(e){
// 监听缓存列表的变化,如果缓存列表中没有当前的路由或组件则在缓存中销毁该实例
let name = this.$options.name;
if(!this.$store.state.keepAliveList.includes(name)) {
this.$destroy()
}
}
},
}
5.完整代码
_1./components/ToWatch.vue

<template> <div class="topwatch" > <el-tag :key="index" v-for="(tag,index) in dynamicTags" closable :effect="tag.active?'dark':'plain'" :disable-transitions="false" @click="tapClick(tag)" @close="tapClose(tag)"> {{tag.name}} </el-tag> </div> </template> <script> export default { name:'Topwatch', props:{ routerVal: Object, }, computed: { isShow() { return this.routerVal } }, watch: { isShow:{ //深度监听,可监听到对象、数组的变化 handler (routerVal) { // do something, 可使用this this.handleInputConfirm(routerVal); }, deep:true } }, data() { return { dynamicTags: [], }; }, methods: { tapClick(tag){ this.$router.push({path:tag.path}) }, tapClose(tag) { //处理keepalive:当关闭标签为缓存组件时,清除其在store里对应keepAliveList if(tag.meta.keepAlive){ this.$store.commit('removeKeepAliveItem',tag.path.substring(1)); } //当关闭标签非第一个标签时,跳到上一个标签所在路由位置,防止destroy后页面视图还存在 if(this.dynamicTags.indexOf(tag)-1>=0){ let goRouter = this.dynamicTags[this.dynamicTags.indexOf(tag)-1].path; console.log(goRouter); this.$router.push({path:goRouter}); }else{ this.$router.push({path:"/indexdata"}); } //清除标签视图 this.dynamicTags.splice(this.dynamicTags.indexOf(tag), 1); }, handleInputConfirm(e) { if(this.dynamicTags!=""){ let routerArr = this.dynamicTags; for(var j in routerArr){ this.$set(this.dynamicTags[j],"active",false); } for(var i in routerArr){ if(routerArr[i].name==e.name){ this.$set(this.dynamicTags[i],"active",true); return; } } } let inputValue = e; if (inputValue) { this.dynamicTags.push(inputValue); //处理keepalive:当生成标签为缓存组件时,添加其在store里对应keepAliveList if(inputValue.meta.keepAlive){ let storeCache = inputValue.path.substring(1); this.$store.commit('setKeepAliveLists',storeCache); } } } } } </script> <style lang="less" scoped> .topwatch{ padding:5px 0; } .el-tag { margin: 5px 0px 5px 8px; cursor: pointer; } .button-new-tag { margin-left: 10px; height: 32px; line-height: 30px; padding-top: 0; padding-bottom: 0; } .input-new-tag { width: 90px; margin-left: 10px; vertical-align: bottom; } </style>
_2.mixin.js

export default { computed: { keepAliveConf(){ return this.$store.state.keepAliveList; } }, watch:{ keepAliveConf(e){ // 监听缓存列表的变化,如果缓存列表中没有当前的路由或组件则在缓存中销毁该实例 let name = this.$options.name; if(!this.$store.state.keepAliveList.includes(name)) { this.$destroy() } } }, }
_3.store/index.js

import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) //创建VueX对象 const store = new Vuex.Store({ state:{ bgColor:'#545c64', textColor:'#fff', activeColor:'#ffd04b', contentBGC:'#fff', contentTextColor:"#222", keepAliveList:[], //保存缓存的列表 }, mutations:{ setKeepAliveLists(state,keepName){ state.keepAliveList.push(keepName); }, removeKeepAliveItem(state,keepName){ state.keepAliveList.splice(state.keepAliveList.indexOf(keepName), 1) }, changeColor(state,val){ if(val==1){ state.bgColor = '#545c64'; state.textColor = '#fff'; state.activeColor = '#ffd04b'; state.contentBGC = '#fff'; state.contentTextColor = "#222"; } if(val==2){ state.bgColor = '#fff'; state.textColor = '#606266'; state.activeColor = '#409EFF'; state.contentBGC = '#fff'; state.contentTextColor = "#222"; } if(val==3){ state.bgColor = '#333333'; state.textColor = '#a29f9f'; state.activeColor = '#e25132'; state.contentBGC = '#f5f5f5'; state.contentTextColor = "#222"; } localStorage.setItem("systemColor",val) } } }) export default store