【问题标题】:Dynamically add v-tab-item while maintaining animation order在保持动画顺序的同时动态添加 v-tab-item
【发布时间】:2021-02-16 12:34:52
【问题描述】:

我正在尝试动态更新 Vuetify <v-tabs-items> 组中显示的项目,但动画无法正常工作。当我选择一个新添加的选项卡时,动画总是表现得好像该选项卡在右侧,尽管它在 DOM 中位于左侧。如何更正此问题,以便选项卡在选项卡栏中出现的顺序反映了移动方向?

在此示例中,请注意对于原始选项卡,单击更右侧的选项卡会使其从右侧动画化。但是,在左侧添加新选项卡后,单击此新选项卡会使其从右侧滑入,而不是从左侧滑入。

Sandbox

<template>
  <v-app>
    <v-card>
      <v-tabs v-model="chosenTab" grow>
        <v-tab v-for="x in xs" :key="x">
          {{ x }}
        </v-tab>
      </v-tabs>
      <v-tabs-items v-model="chosenTab">
        <v-tab-item v-for="x in xs" :key="x">
          <v-card flat>
            <v-card-text>
              {{ x }}
            </v-card-text>
          </v-card>
        </v-tab-item>
      </v-tabs-items>
      <v-card-actions>
        <v-btn @click="xs.unshift('new-tab-' + xs.length)"> Add new tab </v-btn>
      </v-card-actions>
    </v-card>
  </v-app>
</template>

<script>
export default {
  data() {
    return {
      chosenTab: null,
      xs: ["tab-0", "tab-1", "tab-2"],
    };
  },
};
</script>

【问题讨论】:

    标签: javascript vue.js vuetify.js


    【解决方案1】:

    您应该在v-tab 上使用href 属性,在v-tab-item 上使用id 属性 - 否则它将不起作用。选项卡必须具有唯一的字符串标识符 - 依赖默认数字索引容易出错,因为它(数字索引)取决于选项卡的创建顺序而不是它们在 DOM 中的位置。

    每次 VTabs 检测到新选项卡时 - 它都会通过 mixins/groupable/index.js 中的 created() 钩子,该钩子又会调用 VItemGroup.js 中的 register() 方法。新标签总是被推送到带有标签的内部数组 - 所以它们的内部顺序(动画使用)取决于它们的创建顺序。

    除非您修补 Vuetify,否则您无法更改此行为。所以为了克服它 - 你必须key v-tab-item 通过他们的索引而不是他们的ID。是的,这将导致不必要的重新渲染 - 但这是解决这种“错误”Vuetify 行为的代价,直到他们修复它。

    <template>
      <v-app>
        <v-card>
          <v-tabs v-model="chosenTab" grow>
            <v-tab v-for="x in xs" :key="x" :href="'#'+x">
              {{ x }}
            </v-tab>
          </v-tabs>
          <v-tabs-items v-model="chosenTab">
            <v-tab-item v-for="(x,idx) in xs" :key="idx" :id="x">
              <v-card flat>
                <v-card-text>
                  {{ x }}
                </v-card-text>
              </v-card>
            </v-tab-item>
          </v-tabs-items>
          <v-card-actions>
            <v-btn @click="xs.unshift('new-tab-' + xs.length)"> Add new tab </v-btn>
          </v-card-actions>
        </v-card>
      </v-app>
    </template>
    

    【讨论】:

    • 嗨 IVO,对不起,我过度简化了我的 MWE 以排除这些属性,它们存在于我的真实代码中。但是,它们似乎对手头的问题没有任何影响:即使添加 href、value 和 id,动画方向也不会改变。
    • 好吧,对于v-tabv-tab-item,您应该使用数组索引作为key - 而不是您在沙盒中所做的选项卡名称/ID。
    • 这不会维护内容:存储在选项卡元素中的任何数据都不会在每个选项卡中维护。 Key 旨在维护对同一元素的引用,以尽量减少重新渲染,但这会导致每个组件接收前一个的道具,因此 data 不会在每个选项卡中维护
    • 您的问题是因为v-tabs-items 维护带有选项卡的内部数组 - 并且该数组按每个选项卡的创建时间排序,以便每个新选项卡都被推到该数组的后面。您无法更改此行为(除非您修补 Vuetify) - 因此,为了克服它,您应该通过 your 数组中的索引来 key 标签。是的,它会导致不必要的重新渲染 - 但否则您无法解决问题。
    • 好的,谢谢伊沃。如果您将其添加到答案中,我会将其标记为已接受
    猜你喜欢
    • 2018-03-05
    • 2020-10-06
    • 1970-01-01
    • 2015-10-16
    • 2021-03-31
    • 2016-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多