Vue.js <keep-alive> 模板中的广告位无效
Vue.js <keep-alive> in template for slot not working
我正在使用一个名为 'Stepper' 的组件,它是一个基本组件,在顶部有一些步骤来指导用户完成一个过程。在这个步进器中,我们生成了一个动态数量的插槽,我们传入一个组件来填充该插槽。
Stepper.vue
...
<div v-for="step in steps" :key="step.name">
<div class="stepper-pane" v-if="step.name === currentItem.name">
<slot :name="`${step.name}`" />
</div>
</div>
...
Parent.vue
...
<Stepper :items="steps"
<template v-for="step in steps" v-slot:[step.name] :key="step.name">
<keep-alive>
<component :is="step.component" />
</keep-alive>
</template>
</Stepper>
...
<script lang="ts">
...
import Stepper from "@/components/Stepper.vue";
import Component1 from "@/components/Component1.vue";
import Component2 from "@/components/Component2.vue";
export default defineComponent({
name: "ParentComponent",
components: {
Stepper,
Component1,
Component2,
},
setup() {
const steps = ref([
{
name: "step1",
label: "Step 1",
component: "Component1",
},
{
name: "step2",
label: "Step 2",
component: "Component2",
},
]);
return {
steps,
}
}
</script>
总而言之,一切正常。每个步骤的组件显示,步骤递增等等。我们遇到的问题是 <keep-alive>
不工作。每次您在步骤中来回返回时,组件都会重新呈现,我们会看到调用了 onMounted
挂钩。当然,如果需要,我们可以用一些 'saved' 数据预先填充表单,但如果我们能让 <keep-alive>
工作就更好了。我们也尝试将 :include="[COMPONENT_NAMES]"
添加到 <keep-alive>
,但无济于事。
编辑:更新了包含更多详细信息的代码片段。
确保您没有在通常禁用 Chaches 的开发环境中对此进行测试。因此,如果您没有缓存引用,keep-alive 将无法工作。
This means that Vue does not have to create a new instance every single time you switch components. **Instead, it just uses the cached reference whenever you come back to it**. Keep-Alive is what VueJS calls an abstract element – meaning that it does not render a DOM element nor does it show up as a component.
您也可以在控制台工具中禁用缓存。
为了确定您可以检查此设置:
#另一个编辑:
我做了更多研究,并为您的 Keep-alive 组件添加了一个密钥
<component :is="step.component" :key="UniqueIdentifier" />
将帮助您 vue-router 了解此组件已更改。
查看其他 SA 答案:vue Keep-alive not working
<keep-alive>
正在缓存动态 component
,但是 Stepper.vue
中的 v-if
指令删除了 div.stepper-pane
及其 <slot>
(因此在安装新组件之前销毁当前组件)基于 currentItem.name
,这会导致您看到的行为。
解决此问题的一种方法是重构 Stepper.vue
,将列表呈现移动到默认插槽中。对我来说,这是有道理的,因为 Stepper.vue
一次只渲染一个 step/slot。
<!-- ParentComponent.vue -->
<Stepper :currentItem="currentItem">
<keep-alive>
<component :is="currentItem.component" />
</keep-alive>
</Stepper>
<!-- Stepper.vue -->
<div class="stepper-pane">
<slot />
</div>
我正在使用一个名为 'Stepper' 的组件,它是一个基本组件,在顶部有一些步骤来指导用户完成一个过程。在这个步进器中,我们生成了一个动态数量的插槽,我们传入一个组件来填充该插槽。
Stepper.vue
...
<div v-for="step in steps" :key="step.name">
<div class="stepper-pane" v-if="step.name === currentItem.name">
<slot :name="`${step.name}`" />
</div>
</div>
...
Parent.vue
...
<Stepper :items="steps"
<template v-for="step in steps" v-slot:[step.name] :key="step.name">
<keep-alive>
<component :is="step.component" />
</keep-alive>
</template>
</Stepper>
...
<script lang="ts">
...
import Stepper from "@/components/Stepper.vue";
import Component1 from "@/components/Component1.vue";
import Component2 from "@/components/Component2.vue";
export default defineComponent({
name: "ParentComponent",
components: {
Stepper,
Component1,
Component2,
},
setup() {
const steps = ref([
{
name: "step1",
label: "Step 1",
component: "Component1",
},
{
name: "step2",
label: "Step 2",
component: "Component2",
},
]);
return {
steps,
}
}
</script>
总而言之,一切正常。每个步骤的组件显示,步骤递增等等。我们遇到的问题是 <keep-alive>
不工作。每次您在步骤中来回返回时,组件都会重新呈现,我们会看到调用了 onMounted
挂钩。当然,如果需要,我们可以用一些 'saved' 数据预先填充表单,但如果我们能让 <keep-alive>
工作就更好了。我们也尝试将 :include="[COMPONENT_NAMES]"
添加到 <keep-alive>
,但无济于事。
编辑:更新了包含更多详细信息的代码片段。
确保您没有在通常禁用 Chaches 的开发环境中对此进行测试。因此,如果您没有缓存引用,keep-alive 将无法工作。
This means that Vue does not have to create a new instance every single time you switch components. **Instead, it just uses the cached reference whenever you come back to it**. Keep-Alive is what VueJS calls an abstract element – meaning that it does not render a DOM element nor does it show up as a component.
您也可以在控制台工具中禁用缓存。
为了确定您可以检查此设置:
#另一个编辑:
我做了更多研究,并为您的 Keep-alive 组件添加了一个密钥
<component :is="step.component" :key="UniqueIdentifier" />
将帮助您 vue-router 了解此组件已更改。
查看其他 SA 答案:vue Keep-alive not working
<keep-alive>
正在缓存动态 component
,但是 Stepper.vue
中的 v-if
指令删除了 div.stepper-pane
及其 <slot>
(因此在安装新组件之前销毁当前组件)基于 currentItem.name
,这会导致您看到的行为。
解决此问题的一种方法是重构 Stepper.vue
,将列表呈现移动到默认插槽中。对我来说,这是有道理的,因为 Stepper.vue
一次只渲染一个 step/slot。
<!-- ParentComponent.vue -->
<Stepper :currentItem="currentItem">
<keep-alive>
<component :is="currentItem.component" />
</keep-alive>
</Stepper>
<!-- Stepper.vue -->
<div class="stepper-pane">
<slot />
</div>