swiftui动画之tab自定义切换动画_vue 基础-动画过渡 transition 示例

7c6a00c6e02ff3374b7f2cc903e4a9e8.png

前言

《vue 基础》系列是再次回炉 vue 记的笔记,除了官网那部分知识点外,还会加入自己的一些理解。(里面会有大部分和官网相同的文案,有经验的同学择感兴趣的阅读)

讲到动画,说真的我自己用的的确不多,平时大部分时间都在处理业务问题,或者后端服务。

但前端的“产品”都是要给用户看,并且使用的。好的网站除了服务响应快外,页面交互也是出类拔萃的。

这篇就聊下 vue 中怎么来实现动画的过渡效果。

单元素/组件过渡

依靠 vue 提供了 transition 组件标签,来对如下特殊的指令或者标签做 “进入/离开”过渡 效果:

v-if、v-show、动态组件、root 节点。

先来看段代码,看下过渡效果:

3586d078fc8042d002ff52940c7bd7ca.png

当点击 button 后,会控制 show 的值来切换 v-if 所要渲染的模板。能看到 hello 这块内容在 v-if 切换时有个小动画:

721268394c5b9acf257aeb94ddbd7a78.gif

页面效果

那动效怎么产生的呢?

1. 自动嗅探目标元素是否应用了 CSS 过渡或动画,如果是,在恰当的时机添加/删除 CSS 类名。

  • 当显示时:添加样式 xx-enter-active xx-enter-to
  • 当离开时:添加样式 xx-leave-active xx-leave-to
c4d80ec643356f7754f936a8ed32424d.png

页面增加标签

2. 如果过渡组件提供了 JavaScript 钩子函数,这些钩子函数将在恰当的时机被调用。3. 如果没有找到 JavaScript 钩子并且也没有检测到 CSS 过渡/动画,DOM 操作 (插入/删除) 在下一帧中立即执行。(注意:此指浏览器逐帧动画机制,和 Vue 的 nextTick 概念不同)

过渡类名

在进入/离开的过渡中,会有 6 个 class 切换:

v-enter –> v-enter-active –> v-enter-to –> v-leave –> v-leave-active –> v-leave-to

70768a3042a9f4b3783320e8ccba3ad2.png

css 过渡和 css 动画

css 过渡

通过 transition来定义过渡时期的 css 样式:

63284716d4b9d287278cda9ae3dc44c6.png

过渡

css 动画

除了过渡效果,我们还能设置 animation 标签指定 css 动画效果。

7947a6beb38d8ab5deb824f96aaaa57e.png

动画

如何区分 css 过渡和动画共同使用

当然这两者都是 css 范畴的特效知识,根据实际需要使用。

不过可能出现 animation 完成,但 transition 还在继续的情况,对于这种情况需要设置 type=animation|transition 来区分 vue 所要监听的类型。

我们先来看下两种动效单独的使用情况(动画稍显夸张,只为说明现象):

animation

65db5818d24225f25dc703b933f29d70.png

粉色方框按照 animation 设置的进度,逐步放大,直至结束,用时 1s:

c15e2b7a6718eabdd2e86c567f012860.gif

页面效果

transition

5abd908b7819fe97d9323c96ff9cba43.png

红框从 300px 缩小至 100px,用时 3s:

90e3d6c58ed30df450a9c5a7160b1b5e.gif

页面效果

一起使用

ab3de90fd1172e8526d69f5d1028d889.gif

页面效果

因为动效在时间 duration 中存在重叠交叉,所以会出现上面这样变扭的效果,可以动过 type animation|transition 来指定 vue 监听动效的类型加以控制。

比如,我们设置了 animation 就 屏蔽了 transition 的效果,就会和单使用 animation 一样了。

8e5c2dd90e75d406225caa12d706d698.png

设置 type

自定义过渡类名

用于配合第三方 animate 类库时使用。可以根据我们的需要细化效果的展示。

cfb25f550250781d223b6bf6be1d1b76.png
896a4bbf7e1f5fb7208618fc71789caf.png

页面标签

javascript 钩子

可以在标签上绑定过渡各个时期的钩子,通过 js 来调用触发相关事件的事件。

bc74ebbd8881bbb35c3ee56757593fb8.png
e6d5d3694c1a603cf1dc974566c68acc.png

注意:当只用 JavaScript 过渡的时候,在 enter 和 leave 中必须使用 done 进行回调。否则,它们将被同步调用,过渡会立即完成。

多元素过渡

举个多元素过渡的例子:

3ce869f95785dcb5d0a164b49513c758.png

一般情况

如果存在数据就显示 table 内容,不存在就显示一个无数据的文案,然后通过 transition 动效切换不同效果。

但是如果当相同标签元素切换时,就需要通过 key 来区分他们的不同。

3f4d78dc4d5ec2a45faaf51a0844031d.png

相同元素切换

如果 相同元素模板的 key 一致,效果如下:

ade638db33def232f433e760c6916187.gif

相同 key

注意,这不是期望的效果。可能你会感觉到生硬,因为相同 key 的元素切换时没有过渡效果。

设置不同 key 后,动效得以生效:

a0852da6aa3a002e097a9422d862e882.gif

不同 key

对比这两者,是不是后者更为顺滑些。

过渡模式

在两个元素切换的时候,可能我们需要更细致的过渡模式,比如上例中:第一个 button 离开,第二个 button 进来之间的过程中,都被重新绘制了,间隙虽然很短,但能明显看到产生了类似滑动的效果(不符合原始意图)。

vue 提供了 mode 过渡模式:

  • in-out:新元素先进行过渡,完成之后当前元素过渡离开。
  • out-in:当前元素先进行过渡,完成之后新元素过渡进入。

你只要在原有 transition 标签上,添加 mode="out-in" 即可:

135c6fddd4b923231f076d753b92157c.gif

设置 mode

当使用 mode="out-in" 时,第二个元素等待第一个元素消失后才入场,使得原始意图符合预期。

多个组件的过渡

同时 transition 也可以作用于“动态组件”的过渡效果

12b3004997b2b6639bf17e2a3e44aac1.png

列表过渡

与 transition 不同的是,列表过渡需要使用 标签。

4524c4d8f08470ac76e53db22abb4ee2.png

transition-group

能注意到这里设置了 tag='div' ,可以让最后的列表内容包裹在一个 div 标签内。

a14a126d2c493e83897c96c4dccdaf61.gif

上图中,在列表中添加新元素的过渡效果是不是比没有好多了?

针对列表中元素的移动,也有专门的属性来定义:v-move,和 v-enter、v-leave 类似,最后会根据过渡时期来添加指定的样式,用法参见 v-enter 等。

10aaf6532173bdeaddc72dae82683a9b.png

总结

这是 vue 自带的动过效果,来让各个元素切换的过渡时期,用户体验更为流畅。

其实内置还有 FLIP 动画队列,并且根据数据驱动的基础,能做更多的动画特效展示,这块内容你在 vue 官网能看到示例,这里就不做展开了。

关于我

一位“前端工程师”,乐于实践,并分享前端开发经验。

如果有问题或者想法,欢迎各位评论留言,愿大家共同进步。

关注【前端雨爸】,查阅更多前端技术心得。