Vue动画
-
单元素/组件的过渡
-
提供了
transition
的封装组件,用于下列场景- 条件渲染 (使用
v-if
) - 条件展示 (使用
v-show
) - 动态组件
- 组件根节点
- 条件渲染 (使用
-
过渡的类名:
-
v-enter :定义进入过渡的开始状态。在元素被插入之前生效,在元素被插入之后的下一帧移除
.fade-enter { opacity: 0; }
-
v-enter-active :定义进入过渡生效时的状态。在元素被插入之前生效,在过渡/动画完成之后移除
.fade-enter-active { transition: opacity .5s; }
-
v-enter-to : 定义进入过渡的结束状态。在元素被插入之后下一帧生效 (与此同时 v-enter 被移 除),在过渡/动画完成之后移除
.fade-enter-to { opacity: 1; }
-
v-leave : 定义离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除
.fade-leave { opacity: 1; }
-
v-leave-active :定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触 发时立刻生效,在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间,延迟和 曲线函数
.fade-leave-active { transition: opacity .5s; }
-
v-leave-to : 定义离开过渡的结束状态。在离开过渡被触发之后下一帧生效 (与此同时 v-leave 被 删除),在过渡/动画完成之后移除。
.fade-leave-to { opacity: 0; }
-
注意点:对于这些在过渡中切换的类名来说,如果你使用一个没有名字的
<transition>
,则v-
是这些类名的默认前缀。如果你使用了<transition name="my-transition">
,那么v-enter
会替换为my-transition-enter
-
-
CSS
过渡<div id="example-1"> <button @click="show = !show"> Toggle render </button> <transition name="slide-fade"> <p v-if="show">hello</p> </transition> </div>
new Vue({ el: '#example-1', data: { show: true } })
/* 可以设置不同的进入和离开动画 */ /* 设置持续时间和动画函数 */ .slide-fade-enter-active { transition: all .3s ease; } .slide-fade-leave-active { transition: all .8s cubic-bezier(1.0, 0.5, 0.8, 1.0); } .slide-fade-enter, .slide-fade-leave-to { transform: translateX(10px); opacity: 0; }
-
CSS
动画<div id="example-2"> <button @click="show = !show">Toggle show</button> <transition name="bounce"> <p v-if="show">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris facilisis enim libero, at lacinia diam fermentum id. Pellentesque habitant morbi tristique senectus et netus.</p> </transition> </div>
new Vue({ el: '#example-2', data: { show: true } })
.bounce-enter-active { animation: bounce-in .5s; } .bounce-leave-active { animation: bounce-in .5s reverse; } @keyframes bounce-in { 0% { transform: scale(0); } 50% { transform: scale(1.5); } 100% { transform: scale(1); } }
-
-
可以配合使用第三方
CSS
动画库-
自定义过渡的类名
enter-class
enter-active-class
enter-to-class
(2.1.8+)leave-class
leave-active-class
leave-to-class
(2.1.8+)
-
他们的优先级高于普通的类名,这对于 Vue 的过渡系统和其他第三方 CSS 动画库,如 Animate.css 结合使用十分有用。
<link href="https://cdn.jsdelivr.net/npm/animate.css@3.5.1" rel="stylesheet" type="text/css"> <div id="example-3"> <button @click="show = !show"> Toggle render </button> <transition name="custom-classes-transition" enter-active-class="animated tada" leave-active-class="animated bounceOutRight" > <p v-if="show">hello</p> </transition> </div>
new Vue({ el: '#example-3', data: { show: true } })
-
-
JavaScript 钩子
-
可以在属性中声明 JavaScript 钩子,使用
JS
实现动画。<transition v-on:before-enter="beforeEnter" v-on:enter="enter" v-on:after-enter="afterEnter" v-on:enter-cancelled="enterCancelled" v-on:before-leave="beforeLeave" v-on:leave="leave" v-on:after-leave="afterLeave" v-on:leave-cancelled="leaveCancelled" > <!-- ... --> </transition>
// ... methods: { // -------- // 进入中 // -------- beforeEnter: function (el) { // ... }, // 当与 CSS 结合使用时 // 回调函数 done 是可选的 enter: function (el, done) { // ... done() }, afterEnter: function (el) { // ... }, enterCancelled: function (el) { // ... }, // -------- // 离开时 // -------- beforeLeave: function (el) { // ... }, // 当与 CSS 结合使用时 // 回调函数 done 是可选的 //当只用 JavaScript 过渡的时候,在 enter 和 leave 中必须使用 done 进行回调。否则,它们将被同步调用,过渡会立即完成 leave: function (el, done) { // ... done() }, afterLeave: function (el) { // ... }, // leaveCancelled 只用于 v-show 中 leaveCancelled: function (el) { // ... } }
-
可以配合使用第三方 JavaScript 动画库,如
Velocity.js
<!-- Velocity 和 jQuery.animate 的工作方式类似,也是用来实现 JavaScript 动画的一个很棒的选择 --> <script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.3/velocity.min.js"></script> <div id="example-4"> <button @click="show = !show"> Toggle </button> <transition v-on:before-enter="beforeEnter" v-on:enter="enter" v-on:leave="leave" v-bind:css="false" > <p v-if="show"> Demo </p> </transition> </div>
new Vue({ el: '#example-4', data: { show: false }, methods: { beforeEnter: function (el) { el.style.opacity = 0 el.style.transformOrigin = 'left' }, enter: function (el, done) { Velocity(el, { opacity: 1, fontSize: '1.4em' }, { duration: 300 }) Velocity(el, { fontSize: '1em' }, { complete: done }) }, leave: function (el, done) { Velocity(el, { translateX: '15px', rotateZ: '50deg' }, { duration: 600 }) Velocity(el, { rotateZ: '100deg' }, { loop: 2 }) Velocity(el, { rotateZ: '45deg', translateY: '30px', translateX: '30px', opacity: 0 }, { complete: done }) } } })
-
-
初始渲染的过渡
-
可以通过 appear attribute 设置节点在初始渲染的过渡
<transition appear> <!-- ... --> </transition>
-
同样也可以自定义 CSS 类名
<transition appear appear-class="custom-appear-class" appear-to-class="custom-appear-to-class" (2.1.8+) appear-active-class="custom-appear-active-class" > <!-- ... --> </transition>
-
自定义 JavaScript 钩子
transition appear v-on:before-appear="customBeforeAppearHook" v-on:appear="customAppearHook" v-on:after-appear="customAfterAppearHook" v-on:appear-cancelled="customAppearCancelledHook" > <!-- ... --> </transition>
-
-
多个元素的过渡
-
使用
v-if
/v-else
:当有相同标签名的元素切换时,需要通过key
attribute 设置唯一的值来标记以让 Vue 区分它们,否则 Vue 为了效率只会替换相同标签内部的内容<transition> <button v-if="isEditing" key="save"> Save </button> <button v-else key="edit"> Edit </button> </transition
-
过渡模式:
-
in-out
:新元素先进行过渡,完成之后当前元素过渡离开<transition name="fade" mode="in-out"> <!-- ... the buttons ... --> </transition>
-
out-in
:当前元素先进行过渡,完成之后新元素过渡进入<transition name="fade" mode="out-in"> <!-- ... the buttons ... --> </transition>
-
-
-
多个组件的过渡:多个组件的过渡只需要使用动态组件
<transition name="component-fade" mode="out-in"> <component v-bind:is="view"></component> </transition>
-
列表过渡
-
使用
v-for
同时渲染整个列表,使用<transition-group>
组件<transition-group name="list" tag="p"> <span v-for="item in items" v-bind:key="item" class="list-item"> {{ item }} </span> </transition-group>
- 不同于
<transition>
,它会以一个真实元素呈现:默认为一个<span>
。你也可以通过tag
attribute 更换为其他元素 - 过渡模式不可用,因为我们不再相互切换特有的元素
- 内部元素总是需要提供唯一的
key
attribute 值 - CSS 过渡的类将会应用在内部的元素中,而不是这个组/容器本身
- 不同于
-
<transition-group>
组件还有一个特殊之处。不仅可以进入和离开动画,还可以改变定位。要使用这个新功能只需了解新增的v-move
class,它会在元素的改变定位的过程中应用。像之前的类名一样,可以通过name
attribute 来自定义前缀,也可以通过move-class
attribute 手动设置.v-move { transition: transform 1s; }
-
-
可复用的过渡:
-
过渡可以通过
Vue
的组件系统实现复用。要创建一个可复用过渡组件,你需要做的就是将<transition>
或者<transition-group>
作为根组件,然后将任何子组件放置在其中就可以了 -
使用 template
Vue.component('my-special-transition', { template: '\ <transition\ name="very-special-transition"\ mode="out-in"\ v-on:before-enter="beforeEnter"\ v-on:after-enter="afterEnter"\ >\ <slot></slot>\ </transition>\ ', methods: { beforeEnter: function (el) { // ... }, afterEnter: function (el) { // ... } } })
-
使用函数式组件
Vue.component('my-special-transition', { functional: true, render: function (createElement, context) { var data = { props: { name: 'very-special-transition', mode: 'out-in' }, on: { beforeEnter: function (el) { // ... }, afterEnter: function (el) { // ... } } } return createElement('transition', data, context.children) } })
-
-
动态过渡
-
在 Vue 中即使是过渡也是数据驱动的!动态过渡最基本的例子是通过
name
attribute 来绑定动态值<transition v-bind:name="transitionName"> <!-- ... --> </transition>
-
所有过渡 attribute 都可以动态绑定,但我们不仅仅只有 attribute 可以利用,还可以通过事件钩子获取上下文中的所有数据,因为事件钩子都是方法。这意味着,根据组件的状态不同,你的 JavaScript 过渡会有不同的表现
-