请教, vue3 中的 keepalive 与路由结构

2021-05-17 16:12:41 +08:00
 gzf6

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,
      },
    },
  ],
},
2570 次点击
所在节点    Vue.js
8 条回复
christin
2021-05-17 17:26:53 +08:00
直接用 keepalive 包裹 paper 就能得到你要的效果啊 为什么要加判断?
把使用组件的代码也贴一下吧
cw2k13as
2021-05-17 17:39:53 +08:00
你这样不行好像,只能操作 keep 的 include 和 exclude,好几年没写过了,我记得好像在 routerbefore,next 之前更改都无效下一次才生效,你自己研究下
gzf6
2021-05-17 17:50:00 +08:00
@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>
```
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,缓存不消失
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];
}
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 组件上的话如果导致组件重建似乎在实例上的组件缓存也消失了吧,下一个进来整个页面肯定要重新渲染了
OHyn
2021-05-17 18:54:27 +08:00
christin
2021-05-17 19:25:20 +08:00
@gzf6 感觉这样用 v-if 判断有点问题 假设第一次 v-if 命中 keep-alive 渲染了 然后你跳转到 paperdetail keep-alive 又没有命中 导致不渲染
这样来回跳转 keep-alive 是一直在渲染和取消渲染

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/777455

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX