You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vuetify3中v-window内组件重复挂载/渲染问题求助

Vuetify3 v-window组件重复渲染与方法多次调用的解决办法

问题描述

在Vuetify3中使用v-window和v-window-item时,出现组件无触发却重复挂载、方法被多次调用的异常:

  • 页面加载后,首个window-item的按钮方法被调用3次
  • 切换到第2个window-item时,1、2号按钮方法各被调用4次
  • 切换到第3个时,1-3号按钮方法各被调用4次

测试代码如下:

<template>
  <v-window
    v-model="window"
    show-arrows
  >
    <v-window-item
      v-for="n in length"
      :key="n"
    >

      <v-card height="200px" class="d-flex justify-center align-center">
        <v-btn
              variant="text"
              color="teal-accent-4">
              {{ getButtonName(n)}}
        </v-btn>
      </v-card>
    </v-window-item>
  </v-window>
</template>

<script>
export default {
  data: () => ({
    length: 5,
    window: 0,
  }),
  methods: {
    getButtonName(n) {
      const ran = Math.random(1000);
      console.log('getting button name', n, ran);
      return `button${ran}`;
    },
  },
};
</script>

解决方案

1. 避免模板中直接调用方法

Vue模板中的插值表达式会在每次组件渲染周期(包括响应式数据更新、父组件重渲染等)执行,这就是方法被多次调用的核心原因。不要在模板中直接调用带有副作用或计算逻辑的方法,应提前计算好所需数据。

2. 预生成按钮名称数据

在组件初始化时,提前生成所有按钮的名称并存储在data中,模板直接引用预生成的数据即可:

<template>
  <v-window
    v-model="window"
    show-arrows
  >
    <v-window-item
      v-for="(btnName, index) in buttonNames"
      :key="index + 1"
    >
      <v-card height="200px" class="d-flex justify-center align-center">
        <v-btn variant="text" color="teal-accent-4">
          {{ btnName }}
        </v-btn>
      </v-card>
    </v-window-item>
  </v-window>
</template>

<script>
export default {
  data: () => ({
    length: 5,
    window: 0,
    buttonNames: []
  }),
  created() {
    // 初始化时预生成所有按钮名称
    this.buttonNames = Array.from({ length: this.length }, () => {
      const ran = Math.random(1000);
      console.log('generating button name', ran);
      return `button${ran}`;
    });
  }
};
</script>

3. 开启v-window-item的懒加载

Vuetify的v-window默认会提前渲染部分未激活的item,加上lazy属性可以让未激活的window-item仅在第一次切换到时才渲染内部内容,之后保持缓存,避免不必要的重复渲染:

<v-window-item
  v-for="(btnName, index) in buttonNames"
  :key="index + 1"
  lazy
>
  <!-- 内部组件 -->
</v-window-item>

效果验证

结合以上两种修改后:

  • 页面加载时,只会生成一次所有按钮名称(控制台仅打印5次生成日志)
  • 切换window-item时,未激活的item首次切换时才渲染,且不会重复调用生成方法,每个组件仅挂载一次

内容的提问来源于stack exchange,提问作者helloworld

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 15:13:20