Skip to content

Commit e607890

Browse files
committed
feat: 添加统一 keep-alive 支持
1 parent 4ea03d9 commit e607890

File tree

5 files changed

+186
-6
lines changed

5 files changed

+186
-6
lines changed

src/layout/component/AppMain.vue

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
<template>
22
<section class="app-main">
33
<transition name="fade-transform" mode="out-in">
4-
<router-view :key="key" />
4+
<keep-alive :include="cachedViews">
5+
<router-view :key="key" />
6+
</keep-alive>
57
</transition>
68
</section>
79
</template>
@@ -11,6 +13,26 @@ export default {
1113
computed: {
1214
key() {
1315
return this.$route.path;
16+
},
17+
cachedViews() {
18+
return this.$store.state.view.cachedViews;
19+
}
20+
},
21+
watch: {
22+
$route() {
23+
this.addCurrView();
24+
}
25+
},
26+
mounted() {
27+
this.addCurrView();
28+
},
29+
methods: {
30+
addCurrView() {
31+
const {name} = this.$route;
32+
if (name) {
33+
this.$store.dispatch('view/addView', this.$route);
34+
}
35+
return false;
1436
}
1537
}
1638
};

src/router/route.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ const notFoundRoute = {path: '*', redirect: '/404', hidden: true};
3939
* @property {string} componentPath 组件路径
4040
* @property {string} menuName 菜单名称
4141
* @property {string} icon 图标
42+
* @property {string} title 标题
43+
* @property {string} icon 图标
44+
* @property {string} cacheFlag 是否缓存
45+
* @property {string} affix 是否钉在 TAG 栏(暂未实现)
4246
*/
4347

4448
/**
@@ -58,7 +62,7 @@ function menuToRoute(menu) {
5862
path: '',
5963
name: menu.routeName,
6064
component: requireComponent(menu.componentPath),
61-
meta: {title: menu.menuName, icon: menu.icon}
65+
meta: {title: menu.menuName, icon: menu.icon, cacheFlag: menu.cacheFlag}
6266
}
6367
],
6468
meta: {}
@@ -75,7 +79,7 @@ function menuToRoute(menu) {
7579
component: Layout,
7680
hidden: menu.hiddenFlag,
7781
// noRedirect 面包屑中是否可点击导航
78-
meta: {title: menu.menuName, icon: menu.icon, noRedirect: true}
82+
meta: {title: menu.menuName, icon: menu.icon, noRedirect: true, cacheFlag: menu.cacheFlag}
7983
};
8084
return {route, currRoute: route};
8185
}
@@ -87,7 +91,7 @@ function menuToRoute(menu) {
8791
name: menu.routeName,
8892
component: requireComponent(menu.componentPath),
8993
hidden: menu.hiddenFlag,
90-
meta: {title: menu.menuName, icon: menu.icon}
94+
meta: {title: menu.menuName, icon: menu.icon, cacheFlag: menu.cacheFlag}
9195
};
9296
return {route, currRoute: route};
9397
}

src/store/getters.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ const getters = {
66
name: state => state.user.name,
77
roles: state => state.user.roles,
88
userInfo: state => state.user.userInfo,
9-
routes: state => state.user.routes
9+
routes: state => state.user.routes,
10+
visitedViews: state => state.view.visitedViews,
11+
cachedViews: state => state.view.cachedViews
1012
};
1113
export default getters;

src/store/index.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@ import Vuex from 'vuex';
33
import getters from './getters';
44
import app from '@/store/module/app';
55
import user from '@/store/module/user';
6+
import view from '@/store/module/view';
67

78
Vue.use(Vuex);
89

910
const store = new Vuex.Store({
1011
modules: {
1112
app,
12-
user
13+
user,
14+
view
1315
},
1416
getters
1517
});

src/store/module/view.js

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
const state = {
2+
visitedViews: [],
3+
cachedViews: []
4+
};
5+
const mutations = {
6+
ADD_VISITED_VIEW: (state, view) => {
7+
if (state.visitedViews.some(v => v.path === view.path)) return;
8+
state.visitedViews.push(
9+
Object.assign({}, view, {
10+
title: view.meta.title || 'no-name'
11+
})
12+
);
13+
},
14+
ADD_CACHED_VIEW: (state, view) => {
15+
if (state.cachedViews.includes(view.name)) return;
16+
if (view.meta.cacheFlag) {
17+
state.cachedViews.push(view.name);
18+
}
19+
},
20+
DEL_VISITED_VIEW: (state, view) => {
21+
for (const [i, v] of state.visitedViews.entries()) {
22+
if (v.path === view.path) {
23+
state.visitedViews.splice(i, 1);
24+
break;
25+
}
26+
}
27+
},
28+
DEL_CACHED_VIEW: (state, view) => {
29+
const index = state.cachedViews.indexOf(view.name);
30+
index > -1 && state.cachedViews.splice(index, 1);
31+
},
32+
DEL_OTHERS_VISITED_VIEWS: (state, view) => {
33+
state.visitedViews = state.visitedViews.filter(v => {
34+
return v.meta.affix || v.path === view.path;
35+
});
36+
},
37+
DEL_OTHERS_CACHED_VIEWS: (state, view) => {
38+
const index = state.cachedViews.indexOf(view.name);
39+
if (index > -1) {
40+
state.cachedViews = state.cachedViews.slice(index, index + 1);
41+
} else {
42+
// if index = -1, there is no cached tags
43+
state.cachedViews = [];
44+
}
45+
},
46+
DEL_ALL_VISITED_VIEWS: state => {
47+
// keep affix tags
48+
state.visitedViews = state.visitedViews.filter(tag => tag.meta.affix);
49+
},
50+
DEL_ALL_CACHED_VIEWS: state => {
51+
state.cachedViews = [];
52+
},
53+
UPDATE_VISITED_VIEW: (state, view) => {
54+
for (let v of state.visitedViews) {
55+
if (v.path === view.path) {
56+
v = Object.assign(v, view);
57+
break;
58+
}
59+
}
60+
}
61+
};
62+
63+
const actions = {
64+
addView({dispatch}, view) {
65+
dispatch('addVisitedView', view);
66+
dispatch('addCachedView', view);
67+
},
68+
addVisitedView({commit}, view) {
69+
commit('ADD_VISITED_VIEW', view);
70+
},
71+
addCachedView({commit}, view) {
72+
commit('ADD_CACHED_VIEW', view);
73+
},
74+
delView({dispatch, state}, view) {
75+
return new Promise(resolve => {
76+
dispatch('delVisitedView', view);
77+
dispatch('delCachedView', view);
78+
resolve({
79+
visitedViews: [...state.visitedViews],
80+
cachedViews: [...state.cachedViews]
81+
});
82+
});
83+
},
84+
delVisitedView({commit, state}, view) {
85+
return new Promise(resolve => {
86+
commit('DEL_VISITED_VIEW', view);
87+
resolve([...state.visitedViews]);
88+
});
89+
},
90+
delCachedView({commit, state}, view) {
91+
return new Promise(resolve => {
92+
commit('DEL_CACHED_VIEW', view);
93+
resolve([...state.cachedViews]);
94+
});
95+
},
96+
delOthersViews({dispatch, state}, view) {
97+
return new Promise(resolve => {
98+
dispatch('delOthersVisitedViews', view);
99+
dispatch('delOthersCachedViews', view);
100+
resolve({
101+
visitedViews: [...state.visitedViews],
102+
cachedViews: [...state.cachedViews]
103+
});
104+
});
105+
},
106+
delOthersVisitedViews({commit, state}, view) {
107+
return new Promise(resolve => {
108+
commit('DEL_OTHERS_VISITED_VIEWS', view);
109+
resolve([...state.visitedViews]);
110+
});
111+
},
112+
delOthersCachedViews({commit, state}, view) {
113+
return new Promise(resolve => {
114+
commit('DEL_OTHERS_CACHED_VIEWS', view);
115+
resolve([...state.cachedViews]);
116+
});
117+
},
118+
delAllViews({dispatch, state}, view) {
119+
return new Promise(resolve => {
120+
dispatch('delAllVisitedViews', view);
121+
dispatch('delAllCachedViews', view);
122+
resolve({
123+
visitedViews: [...state.visitedViews],
124+
cachedViews: [...state.cachedViews]
125+
});
126+
});
127+
},
128+
delAllVisitedViews({commit, state}) {
129+
return new Promise(resolve => {
130+
commit('DEL_ALL_VISITED_VIEWS');
131+
resolve([...state.visitedViews]);
132+
});
133+
},
134+
delAllCachedViews({commit, state}) {
135+
return new Promise(resolve => {
136+
commit('DEL_ALL_CACHED_VIEWS');
137+
resolve([...state.cachedViews]);
138+
});
139+
},
140+
updateVisitedView({commit}, view) {
141+
commit('UPDATE_VISITED_VIEW', view);
142+
}
143+
};
144+
145+
export default {
146+
namespaced: true,
147+
state,
148+
mutations,
149+
actions
150+
};

0 commit comments

Comments
 (0)