Vue2:`v-leave-active` vs `v-leave-to`

1,220 阅读5分钟

wallhaven-4x15wv.jpg

现在流量都是 Vue3,这是好久之前的笔记一直没整理,现在 outdated 了吗?

前言

之前在回顾 Vue2 文档,发现 v-leave-active 和 v-leave-to 这两个过渡状态令我感到疑惑。

发现疑惑

From DOCS

  1. v-enter:定义进入过渡的开始状态。在元素被插入之前生效,在元素被插入之后的下一帧移除。
  2. v-enter-active:定义进入过渡生效时的状态。在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数。
  3. v-enter-to:2.1.8 版及以上定义进入过渡的结束状态。在元素被插入之后下一帧生效 (与此同时 v-enter 被移除),在过渡/动画完成之后移除。
  4. v-leave:定义离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除。
  5. v-leave-active:定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数。
  6. v-leave-to:2.1.8 版及以上定义离开过渡的结束状态。在离开过渡被触发之后下一帧生效 (与此同时 v-leave 被删除),在过渡/动画完成之后移除。

根据文档描述,可知道 toClass 生命周期 ⊆ activeClass 生命周期。两者唯一区别就是,toClass 比 activeClass 晚一个帧插入。

我想试一下这6个过渡阶段究竟是怎么回事,CODEPEN

经测试,得出现象:

  1. .v-enter 的样式可以放在 .v-enter-active 中,效果是一样的。
  2. .v-leave-to 的样式可以放在 .v-leave-active 中,效果是一样的。

疑惑:.v-enter.v-leave-to会不会多余了?使用场景有什么讲究?无中生有吗?没事找事吗?balalala......

寻找原因

一开始是从百度、Google、掘金、Vue Forum、GitHub上看issues发帖子找答案......,结果就是网上也没有相关的内容,掘金只有一个没什么用的回复。

可能是懒,实在不想看源码。

把文档的说明读了又读,还是不知道作者的意图何在?其实答案的关键点就眼前,注意到2.1.8版本后才加入的两个 toClass。好吧,最好看看 Release Note 就能懂,还是很懒~~

vue@2.1.8 Release Note

其中比较关键的一句是:In order to properly solve #4510, a new type of transition class (-to) is introduced......So using v-leave-to instead of v-leave-active ensures that enter and leave transitions triggered at the same time also start in the exact same frame.

也就是说之前只有 v-leave-active 的时候,enter transitionleave transition 不在同一时间点触发开始,这个可能导致意料之外的情况。再看一下 #4510 这个 issue,究竟是什么特殊情况?我使用 CODEPEN 直接复现一下(问题版本是 v2.1.6):codepen.io/lvjiaxuan/e…

issue现象

通过点击 blue 和 red ,进行切换过渡时,发现蓝色块和红色块之间出现了一条gap(间隙)。而理想情况时移出块和移入块应该是紧密相连的。

简单分析页面打印信息,可得知是 leave transitionenter transition 早开始导致的。

分析原因

问题版本:v2.1.6

github.com/vuejs/vue/b…

在虚拟 dom 添加两个 class 后,nextFrame 真实 dom 第一次被渲染,同时移除 startClass,在下一帧才被触发过渡/动画。

在虚拟 dom 添加两个 class 后,nextFrame 中样式生效,由于真实 dom 之前已经存在,过渡/动画会在这一帧就会被触发。

所以 leave transition 总是比 enter transition 要早一帧以上的时间开始。

第一次修复版本:v.2.1.7

这里,尤是等到了 enter 的元素渲染后,再一起移除 class ,这样就可以同时触发 transition,这是成功的修复。

最终修复版本:v2.1.8

这个版本 revert 了上一版本的修复,toClass 被新增,并被建议使用:So using v-leave-to instead of v-leave-active。其实原理是一样的,transition 都是在同一帧开始。

我想新增 toClass 的意图:

  1. 不想影响 v2.1.6 之前的版本
  2. 原文说了:The class name also more correctly express what it represents.

所以在使用 v-leave-active仍然会出现 gap 。

结论

回到开头的问题:.v-enter.v-leave-to会不会多余了?

首先。 v-enterv-leave 在以前版本,是作为触发 transition 的条件(被移除时触发),但会导致一些 issues 。现在版本,支持了 toClass 被添加时触发 transition。估计由于历史遗留原因,fromClass 被保留了下来。

只使用 v-enter-tov-enter 确实可以写到 v-enter-active 一起,区别就是 transition 被触发开始后,前者样式被移除,后者样式被 toClass 覆盖。

接着。 已经知道了 v-leave-activev-leave-to 不是同一帧添加的,所以严谨一点,两者还是各司其实好了。

反正之后的版本建议使用 toClass 触发 transition,而不是老的 fromClass(v-enter、v-leave),虽然还能用。

总结

  • 开始的困难点主要是自己的例子不合适,一直在单元素过渡上研究,其实 issue 是多元素的例子
  • 然后就是要积极翻 GitHub,翻源码。少看 CDNS,不要 yy