Vue3+Tsx给路由加切换动画时的踩坑及解决
作者:头发掉完就不学了
这篇文章主要介绍了Vue3+Tsx给路由加切换动画时的踩坑及解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
项目场景
用最新的技术栈Vue+Tsx给后台管理系统路由加动画时,语法上与模板语法有些许不同,记录下自己的踩坑记录
样式文件
新建文件transition.scss,这里用的是若依框架人家写好的样式,写好之后在全局引入该样式文件
// global transition css /* fade */ .fade-enter-active, .fade-leave-active { transition: opacity 0.28s; } .fade-enter, .fade-leave-active { opacity: 0; } /* fade-transform */ .fade-transform-leave-active, .fade-transform-enter-active { transition: all 0.5s; } .fade-transform-enter { opacity: 0; transform: translateX(-30px); } .fade-transform-leave-to { opacity: 0; transform: translateX(30px); } /* breadcrumb transition */ .breadcrumb-enter-active, .breadcrumb-leave-active { transition: all 0.5s; } .breadcrumb-enter, .breadcrumb-leave-active { opacity: 0; transform: translateX(20px); } .breadcrumb-move { transition: all 0.5s; } .breadcrumb-leave-active { position: absolute; }
步骤
首先是第一步尝试给路由加过渡动画,代码如下
<div style={{ flex: "1", paddingTop: "12px", height: 0 }}> <Transition name="fade-transform" mode="out-in"> <RouterView v-slots={{ default: ({ Component: RouteComponent }: { Component: any }) => { return <RouteComponent /> } }} ></RouterView> </Transition> </div>
这时候路由完全没动画并且报了一个警告
Component inside <Transition> renders non-element root node that cannot be animated.
意思是在Transition动画节点下只能有一个根节点,这时候再尝试把RouteComponent外面套一层div
<div style={{ flex: "1", paddingTop: "12px", height: 0 }}> <Transition name="fade-transform" mode="out-in"> <RouterView v-slots={{ default: ({ Component: RouteComponent }: { Component: any }) => { return <div><RouteComponent /></div> } }} ></RouterView> </Transition> </div>
这时候还是没有切换动画的,新警告来了
<router-view> can no longer be used directly inside <transition> or <keep-alive>. Use slot props instead: <router-view v-slot="{ Component }"> <transition> <component :is="Component" /> </transition> </router-view>
意思是说router-view不能放在transition下,好的那我们换一种写法试试
<div style={{ flex: "1", paddingTop: "12px", height: 0 }}> <RouterView v-slots={{ default: ({ Component: RouteComponent }: { Component: any }) => { return <Transition name="fade-transform" mode="out-in"> <div> <RouteComponent /></div> </Transition> } }} ></RouterView> </div>
这时候就很完美,没警告了。但是??王德发??切换动效在哪里??我陷入了沉思,官方文档里给的示例是切换显示隐藏的时候用v-if,也就是隐藏的时候dom节点被销毁了,是不是我这个没重新渲染呢??这时候给div加上一个动态的key让它重新渲染就好了
import {useRoute } from 'vue-router'; const route = useRoute()
<div style={{ flex: "1", paddingTop: "12px", height: 0 }}> <RouterView v-slots={{ default: ({ Component: RouteComponent }: { Component: any }) => { return <Transition name="fade-transform" mode="out-in"> <div key={route.path}> <RouteComponent /></div> </Transition> } }} ></RouterView> </div>
这时候就好了,虽然是可以了,但是这个any类型让我很是不舒服,本着一定要写代码优雅的原则,最后改动一下
最终代码
<div style={{ flex: "1", paddingTop: "12px", height: 0 }}> <RouterView v-slots={{ default: ({ Component }: { Component: VNode }) => { return <Transition name="fade-transform" mode="out-in"> <div key={route.path} style={{ height: "100%" }}> {createVNode(Component)} </div> </Transition> } }}/> </div>
这样看着就舒服了
总结
最后想说,TSX真香!走新技术的路上难免会遇到很多坑,但解决了真的很舒服
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。