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
相关产品推荐
相关产品推荐

