动画的类型主要划分为CSS样式动画和JavaScript脚本动画,其中,CSS样式动画可以划分为transition过渡动画和animation逐帧动画。在Vue中只能使用内置组件transition实现单一元素的动画,对于多元素分组动画,则可以使用transition-group组件处理。
基于CSS的样式实现动画效果,开发人员需要编写自定义动画样式。样式的名称不能随意命名,需要遵循一定的规则标准。我们将动画划分为两类,分别是开始动画与结束动画。
开始动画的类名主要有3个,包括v-enter-from(进入动画起始)、v-enter-active(进入动画生效)、v-enter-to(进入动画结束);结束动画的类名与开始动画的类名是对应的,主要有3个,包括v-leave-from(离开动画起始)、v-leave-active(离开动画生效),v-leave-to(离开动画结束),下面通过图2-54演示这6个类名发生的时刻。值得一提的是,动画类名中的v指代的是用户自定义的动画样式类名,而不是字面意义上的v字母。
除了上面这种形式,我们还可以为过渡效果命名。比如fade-enter-active、fade-leave-active等自定义动画样式类名,就是利用fade单词替换了动画类名中的v字母。这就是自定义动画样式的类名规则,即只能使用自定义动画样式名称替换v字母,后面的命名规则不可改变。
现在只需要利用内置组件transition包裹动画元素,并给transition组件设置属性name,name的值对应自定义动画样式名称fade。需要注意的是,transition组件的操控范围只限一个子元素,无法对多个包裹的子元素进行动画样式处理。
图2-54 过渡动画效果中类名发生的时刻
请思考下面代码的运行效果。
点击“切换动画”按钮后可以看到动画元素的显现是一个渐显的过程,而动画元素的隐藏则是一个渐隐的过程,完全实现了基于CSS的过渡动画效果。
CSS的过渡动画只能实现开始与结束的动画效果,而animation逐帧动画却可以实现更丰富、更细腻的动画效果。不过对于Vue来说,不管是过渡动画还是逐帧动画,用户都是利用6个样式类来自定义样式类名,从而实现动画效果的。
比如定义一个slide滑动逐帧动画效果,只需要在slide-enter-active和slide-leave-active中,指定slide-in与slide-out的逐帧动画名称,并在逐帧动画中利用百分比或者from、to来实现 X 轴位移操作。在自定义动画样式后,只需将Vue的transition动画组件的name属性值修改成slide,即可实现指定元素滑入位移和滑出位移的动画效果。
下方代码就是在2.10.1节代码的基础上修改的,读者可自行对比体会,这里不再赘述。
对于Vue的CSS动画,是不是只有自定义动画样式的处理方案呢?其实Vue的CSS动画还可以和第三方动画类库完美结合,从而可以更快、更便捷地实现炫酷的CSS动画效果。
animate.css是一个拥有众多绚丽动画方式的CSS动画类库(这里只做简单演示,相关内容读者可自行查看bootstrap官方网站)。Vue为了更好地与第三方动画类库结合,为transition组件设置了enter-from-class、enter-active-class、enter-to-class、leave-from-class、leave-active-class、leave-to-class 6个样式绑定的属性,这6个属性的名称与之前的CSS动画类名大致相同,意义也相差无几,这里不多做讲解。
我们可以通过CDN的方式引入animate.css CSS动画类库,在遵循其标准的前提下,直接利用transition组件提供的6个属性设置动画效果。任何动画样式都需要先设置animate__animated样式,以此表明它是animate.css提供的动画样式,然后设置特定的动画效果样式名称,比如在enter-active-class中设置animate__bounceInRight,在leave-active-class中设置animate__bounceOutRight后,即可在不写任何自定义动画样式的情况下,实现绚丽的动画效果。
将上面描述的过程通过代码实现,具体如下。
在Vue中,除了利用CSS实现动画效果,还支持JavaScript的操作实现。transition组件提供了8个有关JavaScript动画的钩子函数,主要包括before-enter(动画进入前)、enter(动画进入)、after-enter(动画进入后)、enter-cancelled(进入取消)、before-leave(动画离开前)、leave(动画离开)、after-leave(动画离开后)、leave-cancelled(离开取消)。从名称上来看,这8个transition组件提供的钩子函数与Vue生命周期钩子函数相似,但读者要知道它们是完全不同的。这8个transition组件的钩子函数的位置是在method方法当中,而不是与method方法并列。
Vue动画的钩子函数主要包括两个参数,即el和done,其中,el是要操作的元素目标,done是一个函数,代表过渡是否结束。值得一提的是,当我们想要在@enter和@leave中确认动画是否结束时,可以通过调用done函数来实现,否则钩子函数将被同步调用,过渡将会立即完成,这就会产生与预期动画不一致的结果。
下面利用before-enter、enter、before-leave、leave这4个钩子函数实现一个进度条效果,请读者思考下面的代码。
在上面的代码中,初始进度条div不显示,当点击“切换动画”按钮后,在动画进入前(beforeEnter方法中),为要实现的进度条设置了初始宽度;在动画进入时(enter方法中),通过定时器实现了进度条逐渐增加的效果,并在实现效果后终止动画;在动画离开前(beforeLeave方法中),再次设置进度条初始宽度;在动画离开后(leave方法中),做的事情与动画进入时类似,即通过定时器实现进度条逐渐减少的效果,并在实现效果后终止动画。
运行代码后,可以发现页面上出现了一个按钮,如图2-55所示。首次点击按钮后会发现,页面上出现了一个类似进度条的动画,逐渐增加直至300px,如图2-56所示,再次点击按钮,进度条逐渐减少直至消失(与图2-55效果相同)。
图2-55 初始效果
图2-56 首次点击按钮后出现进度条动画(截图效果)
transition动画组件只能对单一元素进行动画控制,如果想实现列表等多元素的分组动画操作,则需要利用transition-group组件实现。transition组件与transition-group组件的属性基本一致,唯一不同的是,transition-group组件的tag标签属性指定一个元素作为容器元素来渲染,由于transition-group组件控制的是多元素的分组动画,因此必须给它包裹的每个子元素设置唯一的key属性来进行区分,否则无法实现动画效果。
请思考下面代码的运行效果。
上面的代码利用transition-group组件实现了列表的分组动画操作,在transition-group组件上通过tag标签属性指定ul作为容器元素来渲染,并通过列表的形式展示数组。此外,页面上还出现了一个按钮,当点击该按钮时,会在页面上的随机位置添加一个元素,当点击某个元素时,该元素会被移除。初始页面效果如图2-57所示,点击按钮后的页面效果如图2-58所示,点击元素后的页面效果如图2-59所示。
图2-57 初始页面效果
图2-58 点击按钮后的页面效果
图2-59 点击元素后的页面效果