vue3路由切换过渡动画实现(含有一些坑)
今天写项目的准备收尾的时候,想给路由组件切换给一个过渡效果。在开发的过程中遇到一些坑。
1.Vue2和Vue3区别
vue2
<transition :name="transitionName">
<router-view></router-view>
</transition>
后面就是写样式
Vue3
<router-view v-slot="{ Component }">
<transition name="fade">
<keep-alive>
<component :is="Component" />
</keep-alive>
</transition>
</router-view>
后面就是写样式
vue3必须要这样格式套住,不然又bug
官网文档
后面会给一个完整版。
2.开始踩坑
我一开始的写法:
<router-view v-slot="{ Component }">
<transition name="fade">
<keep-alive>
<component :is="Component" />
</keep-alive>
</transition>
</router-view>
css部分:
/* 路由切换动画 */
/* fade-transform */
.fade-leave-active,
.fade-enter-active {
transition: all 0.5s;
}
/* 可能为enter失效,拆分为 enter-from和enter-to */
.fade-enter-from {
opacity: 0;
transform: translateY(-30px);
}
.fade-enter-to {
opacity: 1;
transform: translateY(0px);
}
.fade-leave-to {
opacity: 0;
transform: translateY(30px);
}
注意:
<transform>
标签name
是fade
,那么动画类名前缀也是fade
,例如:fade-leave,fade-enter
运行一看:
路由直接不展示了。还报了警告。然后看了一篇文章说是transition包裹必须是一个根标签,跟着他说的在 <component :is="Component" />给一个div包裹
修改后:
<router-view v-slot="{ Component }">
<transition name="fade">
<keep-alive>
<div>
<component :is="Component" />
</div>
</keep-alive>
</transition>
</router-view>
运行一看,警告没有了,但是我的过度动画没有了。
因为Vue3官网已经说了,每个组件不用像Vue2一样用一个div包裹。我写的vue3组件都是没有div包裹的都是直接写的。
我刚才用div包裹<component :is="Component" />是没有警告,但是没有,于是我就不用div包裹了。给每一个路由组件手动添加一个根标签div
然后这里撤回:
<router-view v-slot="{ Component }">
<transition name="fade">
<keep-alive>
<component :is="Component" />
</keep-alive>
</transition>
</router-view>
到最后就有动画效果了。
但是bug:就是切换路由的时候,第一路由还没离开消失完,第二路由就来了
解决这个很简单,在transition标签加一个mode属性,值看个人要哪一个。
transition 标签元素有一个mode属性,用于设置动画过渡效果。
默认是同时进行元素的进入和离开。元素绝对定位position: absolute;不会有错位问题。
in-out,新元素先进行过渡进入,完成之后当前元素过渡离开。
out-in,当前元素先过渡离开,完成之后新元素过渡进入。
<router-view v-slot="{ Component }">
<transition name="fade" mode="out-in">
<keep-alive>
<component :is="Component" />
</keep-alive>
</transition>
</router-view>
这样就可以了。
但是还有一个地方要注意:
在transition标签还有一个appear属性
是否对初始渲染使用过渡。 * 默认:false
官网连接
如果出现过度动画不生效,可以加这个属性看看,我这里不加也可以生效,大家最好加一下。
3.完整代码
<router-view v-slot="{ Component }">
<transition name="fade" mode="out-in" appear>
<keep-alive>
<component :is="Component" />
</keep-alive>
</transition>
</router-view>
/* 路由切换动画 */
/* fade-transform */
.fade-leave-active,
.fade-enter-active {
transition: all 0.5s;
}
/* 可能为enter失效,拆分为 enter-from和enter-to */
.fade-enter-from {
opacity: 0;
transform: translateY(-30px);
}
.fade-enter-to {
opacity: 1;
transform: translateY(0px);
}
.fade-leave-to {
opacity: 0;
transform: translateY(30px);
}