各位好,我又来请教个 Vue3 的问题,标签页系统使用 defineComponent 创建组件,实现刷新功能。由于组件需要缓存,使用了 keepalive ,于是用 pinia 存储组件的 name 属性,所以创建时在 name 加上时间戳将其表示唯一。
createNode.js
的部分代码片段如下,本意是想看下创建组件时的时间戳:
function getTimeStamp() {
let timeNow = Date.now();
console.log("create: ", timeNow);
return timeNow;
}
export function createNameComponent(component) {
return () => {
return new Promise((resolve) => {
component().then((comm) => {
const tempComm = defineComponent({
name: (comm.default.name || "vueAdminBox") + "_" + getTimeStamp(),
props: comm.default.props || {},
...
当前实现效果如下:
可以看到,组件只有第一次打开时会触发getTimeStamp
函数,关闭再打开就不会重新获取时间戳了。
我期望每次打开标签页都是不同的时间戳,有老哥遇到这个问题吗?
1
shakukansp 68 天前
稍微看了看,你这 router 的 modules 里面每个路由的 component 只调了一次啊
你要重复调用 createNameComponent ,得用 addRoute 和 remove route 修改记录 |
2
jspatrick 68 天前
|
3
leokun 68 天前
|
4
leokun 68 天前
|
5
Artiver OP @leokun
@shakukansp 感谢两位,请问是这样注册动态路由吗,好像还是只会被调用一次。 https://github.com/Artiver/vue3-admin-box/blob/keepalive/src/router/dynamicRegister.js ![20240920 210137]( https://img.z4a.net/images/2024/09/20/20240920_210137.gif) |
6
Artiver OP @jspatrick 感谢,我也看到了 vue-router 的相关说明
https://router.vuejs.org/zh/guide/essentials/dynamic-matching.html#%E5%93%8D%E5%BA%94%E8%B7%AF%E7%94%B1%E5%8F%82%E6%95%B0%E7%9A%84%E5%8F%98%E5%8C%96 不过我看官方说是按照 name 进行 keepalive 的,有其他的方式吗 https://cn.vuejs.org/guide/built-ins/keep-alive.html#include-exclude |
8
shakukansp 67 天前
@Artiver 是让你在点击链接和关闭标签页的时候进行路由的添加删除操作
|
9
etU3NtUmMJhoxInh 67 天前
这个问题可能是因为在组件第一次加载时,getTimeStamp 函数只在组件的生命周期里执行一次,后续打开该组件时,Vue 的缓存机制会导致组件不会重新初始化,因此不会重新调用 getTimeStamp 。
要确保每次打开标签页时都能生成新的时间戳,你需要确保 getTimeStamp 在每次组件实例化时都被调用,而不是只在组件首次加载时调用。你可以通过 Vue 的生命周期钩子来实现,例如 beforeCreate 或 created 。 你可以将 getTimeStamp 放在组件的生命周期钩子中,确保每次组件被加载时都会生成新的时间戳。 function getTimeStamp() { let timeNow = Date.now(); console.log("create: ", timeNow); return timeNow; } export function createNameComponent(component) { return () => { return new Promise((resolve) => { component().then((comm) => { const tempComm = defineComponent({ name: comm.default.name || "vueAdminBox", props: comm.default.props || {}, created() { this.$options.name = (comm.default.name || "vueAdminBox") + "_" + getTimeStamp(); }, }); resolve(tempComm); }); }); }; } |
10
KouShuiYu 67 天前
@Artiver
#6 可以参考我这篇博客 https://chenkai.life/vue/vue%E5%8A%A8%E6%80%81%E7%BB%84%E4%BB%B6%E7%BC%93%E5%AD%98/#%E8%AE%BE%E7%BD%AEcomponent%E7%9A%84key |
11
Artiver OP @jspatrick
@KouShuiYu 是这样的,我应该把需求描述清楚一些,当前是一个文章列表,想复用文章这个组件,动态路由是/article/detail/:id ,希望是每篇文章都能开一个标签页,但是缓存各个组件不受影响,当前因为 name 只会被创建一次,导致无论开多少文章,keepalive 里面只有一个,如果关闭其中一个会导致其他页签都被刷新,所以在寻求方法。 https://img.z4a.net/images/2024/09/20/20240920_210137.gif |
12
Artiver OP @DoYouWantPeach 这个在组件的生命周期里面修改 name 属性,在 router.afterEach 获取不到。
|
13
Artiver OP 感谢各位的意见,已经解决了,其实按照二楼的想法是可以的,按照 path 来缓存,重点是如何更新 keepalive 的值
https://github.com/Artiver/vue3-admin-box/blob/master/src/layout/TabsIndex.vue#L17 参考文章: https://juejin.cn/post/7412548172453494836 |