《vue 基础》系列是再次回炉 vue 记的笔记,除了官网那部分知识点外,还会加入自己的一些理解。(里面会有大部分和官网相同的文案,有经验的同学择感兴趣的阅读)
讲到动画,说真的我自己用的的确不多,平时大部分时间都在处理业务问题,或者后端服务。
但前端的“产品”都是要给用户看,并且使用的。好的网站除了服务响应快外,页面交互也是出类拔萃的。
这篇就聊下 vue 中怎么来实现动画的过渡效果。
依靠 vue 提供了 transition 组件标签,来对如下特殊的指令或者标签做 “进入/离开”过渡 效果:
v-if、v-show、动态组件、root 节点。
先来看段代码,看下过渡效果:
当点击 button 后,会控制 show 的值来切换 v-if 所要渲染的模板。能看到 hello 这块内容在 v-if 切换时有个小动画:
那动效怎么产生的呢?
1. 自动嗅探目标元素是否应用了 CSS 过渡或动画,如果是,在恰当的时机添加/删除 CSS 类名。
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
css 过渡
通过 transition 来定义过渡时期的 css 样式:
css 动画
除了过渡效果,我们还能设置 animation 标签指定 css 动画效果。
当然这两者都是 css 范畴的特效知识,根据实际需要使用。
不过可能出现 animation 完成,但 transition 还在继续的情况,对于这种情况需要设置 type=animation|transition 来区分 vue 所要监听的类型。
我们先来看下两种动效单独的使用情况(动画稍显夸张,只为说明现象):
animation
粉色方框按照 animation 设置的进度,逐步放大,直至结束,用时 1s:
transition
红框从 300px 缩小至 100px,用时 3s:
一起使用
因为动效在时间 duration 中存在重叠交叉,所以会出现上面这样变扭的效果,可以动过 type animation|transition 来指定 vue 监听动效的类型加以控制。
比如,我们设置了 animation 就 屏蔽了 transition 的效果,就会和单使用 animation 一样了。
用于配合第三方 animate 类库时使用。可以根据我们的需要细化效果的展示。
可以在标签上绑定过渡各个时期的钩子,通过 js 来调用触发相关事件的事件。
注意:当只用 JavaScript 过渡的时候,在 enter 和 leave 中必须使用 done 进行回调。否则,它们将被同步调用,过渡会立即完成。
举个多元素过渡的例子:
如果存在数据就显示 table 内容,不存在就显示一个无数据的文案,然后通过 transition 动效切换不同效果。
但是如果当相同标签元素切换时,就需要通过 key 来区分他们的不同。
如果 相同元素模板的 key 一致,效果如下:
注意,这不是期望的效果。可能你会感觉到生硬,因为相同 key 的元素切换时没有过渡效果。
设置不同 key 后,动效得以生效:
对比这两者,是不是后者更为顺滑些。
在两个元素切换的时候,可能我们需要更细致的过渡模式,比如上例中:第一个 button 离开,第二个 button 进来之间的过程中,都被重新绘制了,间隙虽然很短,但能明显看到产生了类似滑动的效果(不符合原始意图)。
vue 提供了 mode 过渡模式:
你只要在原有 transition 标签上,添加 mode="out-in" 即可:
当使用 mode="out-in" 时,第二个元素等待第一个元素消失后才入场,使得原始意图符合预期。
同时 transition 也可以作用于“动态组件”的过渡效果。
与 transition 不同的是,列表过渡需要使用 标签。
能注意到这里设置了 tag='div' ,可以让最后的列表内容包裹在一个 div 标签内。
上图中,在列表中添加新元素的过渡效果是不是比没有好多了?
针对列表中元素的移动,也有专门的属性来定义:v-move,和 v-enter、v-leave 类似,最后会根据过渡时期来添加指定的样式,用法参见 v-enter 等。
这是 vue 自带的动过效果,来让各个元素切换的过渡时期,用户体验更为流畅。
其实内置还有 FLIP 动画队列,并且根据数据驱动的基础,能做更多的动画特效展示,这块内容你在 vue 官网能看到示例,这里就不做展开了。
一位“前端工程师”,乐于实践,并分享前端开发经验。
如果有问题或者想法,欢迎各位评论留言,愿大家共同进步。
关注【前端雨爸】,查阅更多前端技术心得。