了解Vue过渡和动画
transition 元素是帮助我们向元素添加过渡功能的包装器。它提供了不同的钩子,并向不断变化的元素添加了类,这样我们就可以在转换的不同阶段对它们进行样式化。
- enter-from-class
- enter-active-class
- enter-to-class
- leave-from-class
- leave-active-class
- leave-to-class
将自定义库添加到代码中时,这特别有用,稍后,我们会做说明。
<transition
enter-active-class="animated fadeIn zoomIn"
leave-active-class="animated fadeOut zoomOut"
>
...
</transition>
另外,transition元素还会发出JS钩子函数,因此我们可以捕获它们并使用 JS 来执行动画。可用的钩子有:
- before-enter / before-leave
- enter / leave
- after-enter / after-leave
- enter-cancelled / leave-cancelled
transition @before-enter='beforeEnter'>
<!-- ... -->
</transition>
然后,我们可以在 JS 中处理它们。
beforeEnter(el, done) {
done()
}
Vue Transition 高级用法
上面介绍的只是一些基础,在项目中,会遇到比较复杂的场景,这要怎么做呢?
让组件在加载下过渡
这个很简单就能实现了, 只需将appear 属性添加到transition 元素中,如下所示:
<transition name="fade" appear>
...
</transition>
在多个元素之间过渡
假设有两个这样交替的div。
<transition name="fade" appear>
<div v-if="visible">
Option A
</div>
<div v-else>
Option B
</div>
</transition>
我们要做的就是将它们包在transition中,这样过渡样式将同时适用于两者。
要使代码按我们希望的方式起作用,需要注意以下几点:
1. 绝对定位元素
当Vue在两个元素之间过渡时,有时会同时显示两个元素并进行进去/离开的过渡。如果要获得平滑的效果,则可能需要将它们绝对定位在彼此的顶部。
否则,将元素添加到DOM中或从DOM中删除时,这些元素可能只是在各处跳跃。
2.如果元素是一样的,则必须向该组件添加一个key属性
如果元素是一样的,Vue 会尝试优化内容,仅替换元素的内容。根据文档,如果要在多个元素之间进行过渡,最好始终添加 key。
更改过渡时间
Vue 可以检测到过渡/动画何时结束,但是如果我们想设置确切的持续时间,可以通过 duration属性设置 。
我们可以为enter和leave过渡都传递一个值,也可以传有两个值的对象。
<transition :duration="500">...</transition>
...
<transition :duration="{ enter: 1000, leave: 200 }">...</transition>
动态组件之间的转换
我们要做的就是将动态组件包装在transition元素中。
<transition name="fade" appear>
<component :is='componentType' />
</transition>
使用第三方库
假设我们不想自己编写所有的CSS动画。有很多很棒的CSS动画库,可以很容易地将它们合并到VueJS动画中。
在第一个示例中,我们只使用了元素生成的默认类名,但是我们可以做的就是将这些值覆盖到我们想要的任何类中,在这种情况下,它将是CSS库中的类名。
对于我们的示例,我们使用的[Animate.css](https://daneden.github.io/animate.css/) 这个动画库,我们只需将CDN链接添加到我们的index.html文件即可。
// index.html
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.7.2/animate.min.css">
现在,在我们的元素中,我们可以使用enter-active-class和leave-active-class属性将过渡连接到Animate.js。
<transition
enter-active-class="animated fadeIn zoomIn"
leave-active-class="animated fadeOut zoomOut"
>
...
</transition>