Home > other >  Vue3: Using v-for with keep-alive
Vue3: Using v-for with keep-alive

Time:11-12

My Problem

I have a variable number of Tab components; there can be 1 or 10, but only one is going to be displayed at a time. However, I want to cache them between switches. I thought I could put a v-for loop inside a <keep-alive> but according to the docs: https://v3.vuejs.org/api/built-in-components.html#keep-alive:

Note, <keep-alive> is designed for the case where it has one direct child component that is being toggled. It does not work if you have v-for inside it. When there are multiple conditional children, as above, <keep-alive> requires that only one child is rendered at a time.

Question

This seems like a pretty standard use-case, so I'm wondering if there's an easier way about this that I'm missing. Is there a best practice to rendering a variable number of components inside the <keep-alive> component?

Update: Kind of an answer

I was able to separate the Tab logic from the v-for, which means the Tabs get generated elsewhere, while the TabContent is the only thing inside <keep-alive>. Kind of like so:

  <keep-alive>
      <TabContent tab-name="name" />
  </keep-alive>

Then internally, TabContent uses the tab-name prop to grab the data it needs.

Admittedly it feels like a good solution but I'm open to other ways to solve this.

Update 2.0: For Dynamic Components, use :key

The last thing I figured out; my Tab titles are dependent on filenames, and the TabContent is generated from the file, so it takes a filename props. My content was dynamic.

You still can't use a v-for inside the <keep-alive>, but you can use keys still:

  <keep-alive>
    <template>
      <component
        :is="'TabContent'"
        :key="currentTabTitle"
        v-bind="{
          filename: currentTabTitle
        }"
      />
    </template>
  </keep-alive>

CodePudding user response:

Take a look at Dynamic Components with keep-alive

<div id="dynamic-component-demo" >
  <button
     v-for="tab in tabs"
     :key="tab"
     :
     @click="currentTab = tab"
   >
    {{ tab }}
  </button>

<!-- Inactive components will be cached! -->
<keep-alive>
  <component :is="currentTabComponent">     </component>
</keep-alive>
</div>
  • Related