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

Vue动态组件导致<transition appear>页面刷新时重复触发如何解决?

问题原因

这个异常是两个常见的渲染逻辑叠加导致的:

  • 你当前用index作为v-for的key,如果slices是异步获取的数据,刷新页面时会触发两次渲染:第一次是页面初始化slices为空/初始值时的渲染,第二次是异步拿到完整数据后的重渲染,两次都会命中transition的appear触发规则,导致动画重复执行。
  • <transition>的appear属性默认会在组件每次挂载到DOM时都触发入场动画,动态组件在数据更新触发销毁重建时,就会重复触发appear动画。

另外你贴出的代码存在两处语法错误:component-wrapper的class属性少了闭合引号,:key绑定也少了闭合引号,建议先修正避免其他异常。

解决方案

第一步:替换v-for的key值

不要用索引作为key,换成slice的唯一标识(比如slice.id、slice.slice_id这类全局唯一的字段),避免数据更新时组件不必要的销毁重建:

<div 
    class="component-wrapper"
    v-for="slice in slices"
    :key="slice.id"
>
    <component
        :is="slice.slice_type"
        :slice="slice"
    />
</div>

第二步:控制appear的触发时机

通过路由信息判断当前是路由跳转进入还是刷新页面进入,只在路由跳转场景启用appear动画:

Vue3 写法

<script setup>
import { ref } from 'vue'
import { useRoute } from 'vue-router'

const route = useRoute()
// 路由跳转进入时from.name存在,刷新页面时from为空
const enableAppear = ref(!!route.from?.name)
</script>

<template>
  <transition name="slide-in" :appear="enableAppear">
    <!-- 首个需要动画的组件内容 -->
  </transition>
</template>

Vue2 写法

<script>
export default {
  data() {
    return {
      enableAppear: !!this.$route.from?.name
    }
  }
}
</script>

备选方案:异步数据场景延后渲染

如果slices确实是异步接口返回的数据,可以等数据加载完成后再渲染动态组件,从根源避免两次渲染:

<template>
  <!-- 等slices加载完成再渲染 -->
  <div v-if="slices.length">
    <div 
        class="component-wrapper"
        v-for="(slice, index) in slices"
        :key="slice.id"
    >
      <!-- 只给首个组件加动画 -->
      <transition name="slide-in" :appear="index === 0 && enableAppear">
        <component
            :is="slice.slice_type"
            :slice="slice"
        />
      </transition>
    </div>
  </div>
</template>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 14:57:01