Vue 3 – <Transition>渲染无法动画的非元素根节点

问题描述 投票:0回答:12

App.vue 有一个

transition
标签来淡出和淡入页面。

<router-view v-slot="{ Component }">
   <transition name="fade" mode="out-in" appear>
      <component :is="Component"></component>
   </transition>
</router-view>

Page.vue 文件具有简单的结构,但是,它还有一个基本的 sliderjs 组件,该组件会抛出错误

<Transition> renders non-element root node that cannot be animated.
如果删除
transition
标签,则一切正常。

<div v-if="page.isReady">
   <swiper>
      <swiper-slide>Slide 1</swiper-slide>
      <swiper-slide>Slide 2</swiper-slide>
      <swiper-slide>Slide 3</swiper-slide>
   </swiper>
</div>

https://swiperjs.com/vue/

该文件还具有以下内容:

import { Swiper, SwiperSlide } from 'swiper/vue';
import 'swiper/swiper.scss';
    
export default {
  components: {
    Swiper,
    SwiperSlide,
  },
 
  setup () {
    return {
      page: usePage()
    }
  }
}

有什么技巧可以解决这个错误吗?感谢您的任何提示!

vue.js vue-component vuejs3
12个回答
57
投票

没有。

<template>
  <div></div>
  <div>~someone~</div>
</template>

是的。

<template>
  <div>
    <div></div>
    ~someone~
  </div>
</template>

如果您不在“Template”标签内使用“div”标签,您将收到相同的错误。 (顺便说一下,可以使用除 div 标签之外的其他标签)


38
投票

转换需要单个子节点。因此,您可以将

<component>
标签包装在
<div>
内,但是,
<div>
内的普通
<transition>
不会触发转换,但更改
key
属性会触发转换。

我们可以通过获取路由名称来获取唯一的key:

<router-view v-slot="{ Component, route }">
  <transition name="fade" mode="out-in">
    <div :key="route.name">  
      <component :is="Component"></component>
    </div>
  </transition>
</router-view>

这将有效地在具有不同名称的路由之间进行转换,但如果您还想在具有不同参数的同名路由之间进行转换,则可以使用

route.fullPath
而不是
route.name
作为
key


3
投票

我不能完全相信这个……但我遇到了类似的问题,问题是我的视图中有多个节点,并在 Vue.js 论坛上找到了这个人的帖子

也发现了我的错误。转换需要组件中的单根!由于 Vue 3 不再需要组件的单个根节点,我认为这也适用于

transitions

。
但这也是合乎逻辑的。 CSS 需要一个可供过渡引用的根。


3
投票
在具有相同标签名称的元素之间切换时,必须通过赋予它们唯一的键属性来告诉 Vue 它们是不同的元素。否则,Vue 的编译器只会替换元素的内容以提高效率。即使技术上没有必要,始终在组件中键入多个项目也被认为是良好的做法。

<div> <router-link to="/"></router-link> <router-link to="/about"></router-link> </div> <router-view v-slot="{ Component, route }"> <transition name="route" :key="route" mode="out-in"> <component :is="Component" /> </transition> </router-view>
    

1
投票
我解决了,这是一个小错误,html标签外面有一个字符,就在标签后面(逗号)。

<template>, <div> <div> <swiper> <swiper-slide>Slide 1</swiper-slide> <swiper-slide>Slide 2</swiper-slide> <swiper-slide>Slide 3</swiper-slide> </swiper> </div> </div> </template>
    

1
投票
您的动态组件实例必须有一个根元素。 在您的示例中,“Swiper”和“SwiperSlide”必须有一个根元素!


1
投票
不要在路由器的

RouterView

参数中使用
component
。如果您需要这样做,请将其放入根元素中


0
投票
<router-view v-slot="{ Component }"> <transition name="fade" mode="out-in" appear> <!-- root element --> <div> <component :is="Component"></component> </div> </transition> </router-view>
    

0
投票
使用 Nuxt3 对我有用的解决方案:

父页面是:

<template> <NuxtPage /> </template>
但也应该包装到根节点中:

<template> <div> <NuxtPage /> </div> </template>
否则我会遇到转换异常:

组件内部

<Transition>

渲染无法动画的非元素根节点


0
投票
我正在这样做并且有效。

<template> <router-view v-slot="slotProps"> <transition name="route" mode="out-in"> <component :is="slotProps.Component"></component> </transition> </router-view> </template>
    

0
投票
import 'animate.css'; <template> <router-view #default="{Component}"> <transition :enter-active-class="`animate__animated animate__bounceIn`"> <component :is="Component"></component> </transition> </router-view> </template>
    

0
投票
当 VUE 尝试为空模板或同一级别上有 2 个不同项目的模板制作动画时,会发生这种情况。

示例: 这不能动画化

<template> <item1 /> <item2 /> </template>
这可以动画化

<template> <div> <item1 /> <item2 /> </div> </template>
VUE 一次只能对一个元素进行动画处理,因此始终在模板的第一层定义一个元素,它可以是“div”或“span”,无论如何,通常是 div

© www.soinside.com 2019 - 2024. All rights reserved.