vue3,有个路由类似下面的结构,在 Layout 中,keepalive 根据 noCache 判断是否缓存。noCache: true 对 PaperDetail 是生效的,但返回 Paper 时,没有被缓存,导致会重新获取数据。 想达到的效果是:Paper 只在第一次进入时初始化,从 PaperDetail 返回时不会重新初始化。
{
path: '/paper',
name: 'Paper',
component: Layout,
children: [
{
path: '',
name: 'Paper',
component: () => import('@/views/paper/index.vue'),
meta: {
title: 'paper',
},
},
{
path: ':id',
name: 'PaperDetail',
component: () => import('@/views/paper-detail/index.vue'),
meta: {
title: 'paperDetail',
noCache: true,
},
},
],
},
换成这样可以了,只不过不能包在 transition 里
<router-view v-slot="{ Component, route }">
<keep-alive>
<component :is="Component" v-if="!route.meta.noCache" :key="route.name" />
</keep-alive>
<component :is="Component" v-if="route.meta.noCache" :key="route.name" />
</router-view>
1
christin 2021-05-17 17:26:53 +08:00 via iPhone
直接用 keepalive 包裹 paper 就能得到你要的效果啊 为什么要加判断?
把使用组件的代码也贴一下吧 |
2
cw2k13as 2021-05-17 17:39:53 +08:00
你这样不行好像,只能操作 keep 的 include 和 exclude,好几年没写过了,我记得好像在 routerbefore,next 之前更改都无效下一次才生效,你自己研究下
|
3
gzf6 OP @christin 大概像这样
``` <router-view v-slot="{ Component, route }"> <transition :name="route.meta.transition || 'fade-transform'" mode="out-in"> <keep-alive v-if="!route.meta.noCache"> <component :is="Component" /> </keep-alive> <component :is="Component" v-else /> </transition> </router-view> ``` |
4
faceRollingKB 2021-05-17 17:56:10 +08:00
export function CreateKeepAliveRouter(cacheRouters, noCacheRouters = []) {
if(GetJsType(cacheRouters) !== 'Array') { cacheRouters = [cacheRouters] } if(GetJsType(noCacheRouters) !== 'Array') { noCacheRouters = [noCacheRouters] } return { path: '', component: { render(h) { return h('keep-alive', {}, [ h('router-view') ]) } }, children: [ ...cacheRouters, { path: '', component: { data() { return { show: null } }, activated() { this.show = false this.$nextTick(() => { if (this.show === false) { this.show = true } }) }, deactivated() { this.show = null }, render(h) { if (this.show) { return h('router-view') } else { return '' } } }, children: [ ...noCacheRouters ] } ] } } // 用法 routers = [ {...}, // 路由 1 CreateKeepAliveRouter([ {...}, // 路由 2 ], [ {...}, // 路由 3 ]) ] 效果: 1 、只有路由 2 有缓存效果 2 、路由 2 --> 路由 1 --> 路由 2,缓存消失 3 、路由 2 --> 路由 3 --> 路由 2,缓存不消失 |
5
faceRollingKB 2021-05-17 17:57:08 +08:00
// export type JsType = 'Array' | 'String' | 'Symbol' | 'Number' | 'Null' | 'Undefined' | 'Object' | 'RegExp' | 'Date' | 'Boolean' | 'HTMLAnchorElement' | string;
export function GetJsType(val) { return Object.prototype.toString.apply(val).match(/\[object\s([a-zA-Z]+)\]/)[1]; } |
6
sujin190 2021-05-17 18:00:39 +08:00
<keep-alive>
<router-view v-if="!route.meta.noCache" /> </keep-alive> <router-view v-if="route.meta.noCache" /> 似乎应该这样写吧,似乎 keep-alive 底层的组件缓存是放在当前实例上的,不是全局缓存,if 放在 keep-alive 组件上的话如果导致组件重建似乎在实例上的组件缓存也消失了吧,下一个进来整个页面肯定要重新渲染了 |
7
OHyn 2021-05-17 18:54:27 +08:00
|
8
christin 2021-05-17 19:25:20 +08:00 via iPhone
@gzf6 感觉这样用 v-if 判断有点问题 假设第一次 v-if 命中 keep-alive 渲染了 然后你跳转到 paperdetail keep-alive 又没有命中 导致不渲染
这样来回跳转 keep-alive 是一直在渲染和取消渲染 |