在需要组件缓存的页面路由添加keep-alive属性 为true
[{
path: 'text',
component: () =>
import('@/views/text/index'),
name: 'text',
meta: { title: 'text', needRole: true, keepAlive: true }
},
在app.vue中加入keep-alive 标签 <script>标签中导入vuex
<template>
<div id="app">
<keep-alive :include="cachedViews" :max="10">
<router-view />
</keep-alive>
</div>
</template>
import store from '@/store'
import { mapGetters } from 'vuex'
export default {
name: 'App',
computed: {
...mapGetters(['cachedViews'])
},
watch: {
$route: {
handler(newVal) {
const {
name,
meta: { keepAlive }
} = newVal
if (name && keepAlive) {
store.dispatch('tagsView/addCachedView', newVal)
}
},
immediate: true
}
}
}
Vuex store/moudle/tagView.js 缓存组件(增加,删除,更新)
const state = {
visitedViews: [],
cachedViews: []
}
const mutations = {
ADD_VISITED_VIEW: (state, view) => {
if (state.visitedViews.some(v => v.path === view.path)) return
state.visitedViews.push(
Object.assign({}, view, {
title: view.meta.title || 'no-name'
})
)
},
ADD_CACHED_VIEW: (state, view) => {
if (state.cachedViews.includes(view.name)) return
if (!view.meta.noCache) {
state.cachedViews.push(view.name)
}
},
DEL_VISITED_VIEW: (state, view) => {
for (const [i, v] of state.visitedViews.entries()) {
if (v.path === view.path) {
state.visitedViews.splice(i, 1)
break
}
}
},
DEL_CACHED_VIEW: (state, view) => {
const index = state.cachedViews.indexOf(view.name)
index > -1 && state.cachedViews.splice(index, 1)
},
DEL_OTHERS_VISITED_VIEWS: (state, view) => {
state.visitedViews = state.visitedViews.filter(v => {
return v.meta.affix || v.path === view.path
})
},
DEL_OTHERS_CACHED_VIEWS: (state, view) => {
const index = state.cachedViews.indexOf(view.name)
if (index > -1) {
state.cachedViews = state.cachedViews.slice(index, index + 1)
} else {
// if index = -1, there is no cached tags
state.cachedViews = []
}
},
DEL_ALL_VISITED_VIEWS: state => {
// keep affix tags
const affixTags = state.visitedViews.filter(tag => tag.meta.affix)
state.visitedViews = affixTags
},
DEL_ALL_CACHED_VIEWS: state => {
state.cachedViews = []
},
UPDATE_VISITED_VIEW: (state, view) => {
for (let v of state.visitedViews) {
if (v.path === view.path) {
v = Object.assign(v, view)
break
}
}
}
}
const actions = {
addView({ dispatch }, view) {
dispatch('addVisitedView', view)
dispatch('addCachedView', view)
},
addVisitedView({ commit }, view) {
commit('ADD_VISITED_VIEW', view)
},
addCachedView({ commit }, view) {
commit('ADD_CACHED_VIEW', view)
},
delView({ dispatch, state }, view) {
return new Promise(resolve => {
dispatch('delVisitedView', view)
dispatch('delCachedView', view)
resolve({
visitedViews: [...state.visitedViews],
cachedViews: [...state.cachedViews]
})
})
},
delVisitedView({ commit, state }, view) {
return new Promise(resolve => {
commit('DEL_VISITED_VIEW', view)
resolve([...state.visitedViews])
})
},
delCachedView({ commit, state }, view) {
return new Promise(resolve => {
commit('DEL_CACHED_VIEW', view)
resolve([...state.cachedViews])
})
},
delOthersViews({ dispatch, state }, view) {
return new Promise(resolve => {
dispatch('delOthersVisitedViews', view)
dispatch('delOthersCachedViews', view)
resolve({
visitedViews: [...state.visitedViews],
cachedViews: [...state.cachedViews]
})
})
},
delOthersVisitedViews({ commit, state }, view) {
return new Promise(resolve => {
commit('DEL_OTHERS_VISITED_VIEWS', view)
resolve([...state.visitedViews])
})
},
delOthersCachedViews({ commit, state }, view) {
return new Promise(resolve => {
commit('DEL_OTHERS_CACHED_VIEWS', view)
resolve([...state.cachedViews])
})
},
delAllViews({ dispatch, state }, view) {
return new Promise(resolve => {
dispatch('delAllVisitedViews', view)
dispatch('delAllCachedViews', view)
resolve({
visitedViews: [...state.visitedViews],
cachedViews: [...state.cachedViews]
})
})
},
delAllVisitedViews({ commit, state }) {
return new Promise(resolve => {
commit('DEL_ALL_VISITED_VIEWS')
resolve([...state.visitedViews])
})
},
delAllCachedViews({ commit, state }) {
return new Promise(resolve => {
commit('DEL_ALL_CACHED_VIEWS')
resolve([...state.cachedViews])
})
},
updateVisitedView({ commit }, view) {
commit('UPDATE_VISITED_VIEW', view)
}
}
export default {
namespaced: true,
state,
mutations,
actions
}
Vuex store/getter.js
const getters = {
visitedViews: state => state.tagsView.visitedViews,
cachedViews: state => state.tagsView.cachedViews,
}
export default getters
Vuex store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import getters from './getters'
Vue.use(Vuex)
const store = new Vuex.Store({
modules,
getters
})
export default store
页面设置 beforeRouteLeave生命周期函数 定义去往哪些页面需要缓存
import store from '@/store'
beforeRouteLeave(to, from, next) {
// 去这些界面我需要缓存
const routerArr = []
if (!routerArr.includes(to.name)) {
// 不在缓存列表中,从cachedViews缓存列表中移除
store.dispatch('tagsView/delCachedView', from)
}
next()
}