在vue3构建的工程里面,我是用keep-alive实现tab页面加载,本来的想法是tab切换后页面能缓存下来,不需要重复初始化,但发现每次切换都会重复初始化一次tab。
查资料发现keep-alive的include属性要求的是组件的name,而不是路由信息的name,调整后仍是不行,折腾了很久,暂时还没定位到问题,期待大神的回复~~
index.vue页面组件代码定义:
interface State {
visibleAdd: boolean | false,
visibleEdit: boolean | false,
visibleDetail: boolean | false,
}
export default defineComponent({
name: 'systemDict',
components: { DictInfoAdd, DictInfoEdit, DictInfoDetail, DictInfoList },
setup() {
const listSearchFef = ref();
const selectRow = reactive({});
const state = reactive<State>({
visibleAdd: false,
visibleEdit: false,
visibleDetail: false,
});
router-view的定义:
<template>
<div class="h100">
<router-view v-slot="{ Component }">
<transition :name="setTransitionName" mode="out-in">
<keep-alive :include="['systemDict']" :exclude="[]">
<component :is="Component" :key="$route.path" class="w100" />
</keep-alive>
</transition>
</router-view>
</div>
</template>
路由信息的定义:
{
path: '/system/dict',
name: 'systemDict',
redirect: '',
component: () => import('/@/views/system/dict-info/index.vue'),
meta: {
title: '字典管理',
isLink: '',
isHide: false,
isKeepAlive: true,
isAffix: false,
isIframe: false,
funcId: 'systemDict',
icon: 'ele-Document',
},
children: []
},
从代码看,我把 include写死保持和index.vue定义的name一致,发现仍是不行。我在index页面放了大量的输入框,发现切换tab后再切换回来,输入框内容则全部被清空,显然是页面被重新做了初始化,不明白为什么会这样。
我尝试把include的属性去掉,发现tab来回切换后文本框内容不会被清空,如下写法:
<template>
<div class="h100">
<router-view v-slot="{ Component }">
<transition :name="setTransitionName" mode="out-in">
<keep-alive>
<component :is="Component" :key="$route.path" class="w100" />
</keep-alive>
</transition>
</router-view>
</div>
</template>
类似的实现思路在vue2实现没问题,没理解为何在vue3环境则不行,期望在使用include属性下仍能正常缓存页面信息。
你的思路是没问题,你这个写法放在vue2里也确实没问题。你的问题主要是集中在为什么include不生效。
下面我给你举个例子,你可以尝试一下。
假如你想让 systemDict 这个页面进行缓存,那么你保持你原先的写法 还是为
<keep-alive :include="['systemDict']" ><keep-alive>
注意:这时候router.js中的代码不用动,然后在systemDict这个页面中再进行一次name的声明,例如
<template>
内容
</template>
<script>
//注意这个地方要声明name
export default { name: 'systemDict' };
</script>
<script setup>
//业务逻辑代码
</script>