Skip to content

Commit 04f9824

Browse files
committed
缓存
1 parent 7449656 commit 04f9824

File tree

12 files changed

+146
-47
lines changed

12 files changed

+146
-47
lines changed

src/components/global/view/index.vue

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,23 @@
11
<script setup>
2-
defineProps({
2+
import { cacheHandle } from '@/utils/cache'
3+
4+
const props = defineProps({
35
// 过度动画 不传则没有动画
46
transition: {
57
type: String,
68
default: () => ''
9+
},
10+
rename: {
11+
type: Boolean,
12+
default: () => false
713
}
814
})
915
16+
const route = useRoute()
17+
1018
const menuStore = useMenuStore()
11-
const tabsStore = useTabsStore()
12-
const keepalives = computed(() => {
13-
const list = []
14-
fo:for (let i = 0; i < tabsStore.tabs.length; i++) {
15-
const tab = tabsStore.tabs[i]
16-
for (let j = 0; j < menuStore.keepaliveMenus.length; j++) {
17-
const menu = menuStore.keepaliveMenus[j]
18-
if (menu.id === tab.menuId) {
19-
list.push(menu.componentName)
20-
continue fo
21-
}
22-
}
23-
}
24-
return list
25-
})
19+
20+
const keepalives = computed(() => menuStore.keepaliveNames)
2621
2722
/**
2823
* 开始进入动画时将父级元素 overflow 设置为空
@@ -52,13 +47,13 @@ const onLeave = (el) => {
5247
@enter="onEnter"
5348
@leave="onLeave">
5449
<keep-alive :include="keepalives">
55-
<component :is="Component" />
50+
<component :is="rename ? cacheHandle(Component, route) : Component" />
5651
</keep-alive>
5752
</transition>
5853
</template>
5954
<template v-else>
6055
<keep-alive :include="keepalives">
61-
<component :is="Component" />
56+
<component :is="rename ? cacheHandle(Component, route) : Component" />
6257
</keep-alive>
6358
</template>
6459
</router-view>

src/router/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,13 @@ function formatMenus(menus) {
9595
* @returns
9696
*/
9797
function menu2Route(menu) {
98-
const { id, name, type, url, routePath, routeName, redirectName, tab, keepalive, multiple, children } = menu
98+
const { id, name, type, url, routePath, routeName, redirectName, componentName, tab, keepalive, multiple, children } = menu
9999
const meta = {
100100
id: id,
101101
label: name,
102102
type: type,
103103
url: url,
104+
componentName: componentName,
104105
dynamic: true,
105106
tab: tab === 1,
106107
keepalive: keepalive === 1,

src/stores/modules/menu.js

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
import { adminerMenuApi } from '@/api/auth'
2+
import { useTabsStore } from './tabs'
3+
// console.log(useTabsStore())
24

35
import { getLoad, setLoad, clearLoad, getMenuAndPermission, setMenuAndPermission, clearMenuAndPermission } from '@/utils/storage'
46
import { MENU_KEY, PERMISSION_KEY } from '@/utils/constant'
57
import { MenuType } from '@/utils/enum'
68
import { parseData2Tree, clearJson } from '@/utils'
9+
import { findKeepaliveName } from '@/utils/cache'
710

811
const load = getLoad()
912
const data = getMenuAndPermission()
@@ -28,6 +31,7 @@ export const useMenuStore = defineStore('menu', {
2831
url: item.url,
2932
path: item.type === 3 ? `/i-${ item.id }` : item.routePath || (item.url ? `/${ defaultValue }` : ''),
3033
name: item.type === 3 ? `i-${ item.id }` : item.routeName || (item.url ? defaultValue : ''),
34+
componentName: item.componentName,
3135
parentId: item.parentId,
3236
children: []
3337
}
@@ -45,17 +49,21 @@ export const useMenuStore = defineStore('menu', {
4549
url: item.url,
4650
path: item.type === 3 ? `/i-${ item.id }` : item.routePath || (item.url ? `/${ defaultValue }` : ''),
4751
name: item.type === 3 ? `i-${ item.id }` : item.routeName || (item.url ? defaultValue : ''),
52+
componentName: item.componentName,
4853
parentId: item.parentId,
4954
children: []
5055
}
5156
})
5257
return parseData2Tree(reulst)
5358
},
5459
keepaliveMenus: (state) => {
55-
return state.menus.filter(item => item.keepalive && item.componentName && item.componentName.trim())
60+
const list = state.menus.filter(item => item.keepalive && item.componentName && item.componentName.trim())
61+
return parseData2Tree(list)
5662
},
57-
keepaliveMenuIds: (state) => {
58-
return state.menus.filter(item => item.keepalive && item.componentName && item.componentName.trim()).map(item => item.id)
63+
keepaliveNames: (state, a) => {
64+
// console.log(useTabsStore())
65+
return findKeepaliveName(useTabsStore().tabs, state.keepaliveMenus)
66+
// return useTabsStore().tabs
5967
}
6068
},
6169
actions: {

src/stores/modules/tabs.js

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import router from '@/router'
22

3-
// todo: ITab value 格式:{a}-{b}-{c}-{d}
3+
// todo: ITab value 格式:{a}&{b}&{c}&{d}
44
// todo: a: 路由name b: 菜单ID c: 路由query字符串 d: 路由params字符串
55
// todo: c、d 支持多开的时候需要
66
const defaultTabs = [{
7-
value: 'home-home-{}-{}',
7+
value: 'home&home&{}&{}',
88
label: '首页',
99
name: 'home',
1010
path: '/home',
@@ -19,22 +19,27 @@ export const useTabsStore = defineStore('tabs', {
1919
active: '',
2020
tabs: []
2121
}),
22-
getters: {},
22+
getters: {
23+
activeTab: (state) => {
24+
const exists = state.tabs.filter(tab => tab.value === state.active)
25+
return exists.length ? exists[0] : {}
26+
}
27+
},
2328
actions: {
2429
/**
2530
* 路由变化事件 设置当前选中、添加标签
2631
* @param {*} route
2732
*/
2833
changeHandle(route) {
2934
const meta = route.meta
30-
let val = `${ route.name }-${ meta.id }`
35+
let val = `${ route.name }&${ meta.id }`
3136
if (meta.tab) {
3237
if (meta.multiple) {
3338
const queryStr = JSON.stringify(route.query)
3439
const paramsStr = JSON.stringify(route.params)
35-
val += `-${ queryStr }-${ paramsStr }`
40+
val += `&${ queryStr }&${ paramsStr }`
3641
} else {
37-
val += `-{}-{}`
42+
val += `&{}&{}`
3843
}
3944
// 如果不存在则添加
4045
if (this.tabs.every(item => item.value !== val)) {

src/utils/cache.js

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
// 缓存
2+
const cacheMap = new Map()
3+
4+
/**
5+
* 根据路由名称、query和params参数 转成组件名称
6+
* @param {*} name 路由名称
7+
* @param {*} query 路由query参数
8+
* @param {*} params 路由params参数
9+
*/
10+
const routeToComponentName = (name, query, params) => {
11+
let result = name
12+
for (const key in query) {
13+
result += `&${ key }=${ query[key] }`
14+
}
15+
for (const key in params) {
16+
result += `&${ key }=${ params[key] }`
17+
}
18+
return result
19+
}
20+
/**
21+
* 根据标签页的value 转成JSON对象
22+
* @param {*} value tab value 值
23+
*/
24+
const tabValueToJson = (value) => {
25+
const values = value.split('&')
26+
const name = values[0]
27+
const query = JSON.parse(values[2])
28+
const params = JSON.parse(values[3])
29+
return { name, query, params }
30+
}
31+
/**
32+
* 根据标签页的value 转成组件名称
33+
* @param {*} value tab value 值
34+
*/
35+
const tabValueToComponentName = (value) => {
36+
const { name, query, params } = tabValueToJson(value)
37+
return routeToComponentName(name, query, params)
38+
}
39+
40+
/**
41+
* 组件缓存处理
42+
* @param {*} component 组件
43+
*/
44+
export const cacheHandle = (component, route) => {
45+
const { name, query, params, meta: { multiple } } = route
46+
if (multiple) {
47+
const key = routeToComponentName(name, query, params)
48+
let cache
49+
if (cacheMap.has(key)) {
50+
cache = cacheMap.get(key)
51+
} else {
52+
cache = {
53+
name: key,
54+
render: () => h(component)
55+
}
56+
cacheMap.set(key, cache)
57+
}
58+
return cache
59+
}
60+
return component
61+
}
62+
63+
/**
64+
* 递归查询需要缓存的组件名称
65+
* @param {*} menus 可以缓存的菜单列表
66+
*/
67+
export const findKeepaliveName = (tabs, menus) => {
68+
const list = []
69+
for (let i = 0; i < menus.length; i++) {
70+
const { id, componentName, multiple, children } = menus[i]
71+
for (let j = 0; j < tabs.length; j++) {
72+
const { menuId, value } = tabs[j]
73+
if (menuId === id) {
74+
let name = componentName
75+
if (multiple) {
76+
name = tabValueToComponentName(value)
77+
}
78+
list.push(name)
79+
}
80+
}
81+
if (children && children.length) {
82+
const arr = findKeepaliveName(children)
83+
if (arr.length) {
84+
componentName && list.push(componentName)
85+
list.push(...arr)
86+
}
87+
}
88+
}
89+
return list
90+
}

src/views/layout/components/tabsbar/index.vue

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,13 @@ const removeHandle = (name) => {
2929
3030
onBeforeRouteUpdate((to) => {
3131
tabsStore.changeHandle(to)
32-
const meta = to.meta
33-
if (meta.multiple) {
34-
refresh.value = true
35-
nextTick(() => {
36-
refresh.value = false
37-
})
38-
}
32+
// const meta = to.meta
33+
// if (meta.multiple) {
34+
// refresh.value = true
35+
// nextTick(() => {
36+
// refresh.value = false
37+
// })
38+
// }
3939
})
4040
4141
onBeforeMount(() => {

src/views/layout/index.vue

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
<Tabsbar />
1010
</template>
1111
<template #default v-if="!refresh">
12-
<View class="margin-20 flex-item_f-1" transition="left-in-right-out" />
12+
<View class="margin-20 flex-item_f-1" transition="left-in-right-out" rename />
1313
</template>
1414
</component>
1515
<Websocket />
@@ -49,11 +49,6 @@ const component = computed(() => {
4949
}
5050
return result
5151
})
52-
53-
onMounted(() => {
54-
const instance = getCurrentInstance()
55-
console.log(instance)
56-
})
5752
</script>
5853

5954
<style lang="scss">

src/views/modules/develop/menu/index.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ onBeforeMount(() => {
282282
<el-form-item label="是否支持tab页签多开(如:用户1的详情页、用户2的详情并存在tab页签)" prop="multiple">
283283
<DictRadio v-model="form.multiple" code="WHETHER" :disabled="readonly" />
284284
</el-form-item>
285-
<el-form-item label="是否支持缓存" prop="keepalive">
285+
<el-form-item label="是否支持缓存(若是路由不设置缓存,但其下的菜单或路由设置了缓存,那么离开这个路由页将不会继续缓存)" prop="keepalive">
286286
<DictRadio v-model="form.keepalive" code="WHETHER" :disabled="readonly" />
287287
</el-form-item>
288288
</template>

src/views/modules/nest-router/index.vue

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<template>
2-
<div class="nest-router">
2+
<div class="nest-router width-300">
33
<h1>嵌套路由</h1>
4+
<el-input v-model="value" placeholder="输入内容测试页面缓存" />
45
<el-button @click="jump(1)">路由一</el-button>
56
<el-button @click="jump(2)">路由二</el-button>
67
<div class="padding_t-20">
@@ -11,6 +12,7 @@
1112

1213
<script setup>
1314
defineOptions({ name: 'NestRouter' })
15+
const value = ref('')
1416
1517
const router = useRouter()
1618
const jump = (type) => {

src/views/modules/nest-router/modules/router1.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
<template>
22
<div class="width-300">
33
<h2>路由一</h2>
4-
<!-- <el-input v-model="value" placeholder="输入内容测试页面缓存" /> -->
4+
<el-input v-model="value" placeholder="输入内容测试页面缓存" />
55
</div>
66
</template>
77

88
<script setup>
9-
defineOptions({ name: 'Router1' })
9+
defineOptions({ name: 'NestRouter1' })
1010
const value = ref('')
1111
</script>
1212

0 commit comments

Comments
 (0)