在 Vue.js 中使用 Velocity.js
Vue.js 是目前人气很高的前端框架之一, 看看 github 上的 star 就知道了,Vue 中除了css过渡动画,还可以实现 js动画,Velocity.js 就可以完美运用其中(官方例子)
1. 使用 js钩子函数
在 Vue 中实现 js动画,一般会通过 Vue 提供的几个 js 钩子函数 搭配v-show指令来实现,钩子函数会在元素进场或离场状态时自动调用,下面列举了常用的6个钩子函数(函数名可自定义):
JavaScript
// ...
methods: {
// --------
// 进入中
// --------
// 在元素即将显示时
beforeEnter: function (el) {
// ...
},
// 在 beforeEnter 之后,元素运行进场动画时
enter: function (el, done) {
// 这里第二个参数 done 就是下面的 afterEnter 函数
done()
},
// 元素进场动画 enter 结束时
afterEnter: function (el) {
// ...
},
// --------
// 离开时
// --------
// 元素即将隐藏时
beforeLeave: function (el) {
// ...
},
// 在 beforeLeave 之后,元素运行离场动画时
leave: function (el, done) {
// 这里第二个参数 done 就是下面的 afterLeave 函数
done()
},
// 元素离场动画 leave 结束时
afterLeave: function (el) {
// ...
}
}
Vue 中具体使用 velocity.js 的示例:
HTML
<div id="app">
<transition
name="showRect"
@before-enter="handleBeforeEnter"
@enter="handleEnter"
@after-enter="handleAfterEnter"
@before-leave="handleBeforeLeave"
@leave="handleLeave"
@after-leave="handleAfterLeave"
:css="false"
>
<div class="rect" v-show="show"></div>
</transition>
<button @click="handleClick">切换显示方块</button>
</div>
<script src="other/vue@2.5.16"></script>
<script src="http://cdn.jsdelivr.net/npm/velocity-animate@1.5.0/velocity.min.js"></script>
推荐对于仅使用 js过渡的 元素添加v-bind:css="false",Vue 会跳过 CSS 的检测,这也可以避免过渡过程中 CSS 的影响。
CSS
.rect {
width: 50px;
height: 50px;
background: #4dd0e1;
}
JavaScript
var vm = new Vue({
el: '#app',
data: {
// show状态决定方块是显示还是隐藏
show: false
},
methods: {
handleClick: function () {
this.show = !this.show;
},
handleBeforeEnter: function (el) {
el.style.opacity = 0;
console.log('方块显示动画即将执行');
},
handleEnter: function (el, done) {
Velocity(el, 'stop');
Velocity(el, {
backgroundColor: '#0085eb',
opacity: 1,
translateX: 260,
rotateZ: ['360deg', 0]
}, {
duration: 1000,
easing: [ 0.4, 0.01, 0.165, 0.99 ],
complete: done
});
console.log('方块显示动画执行中...');
},
handleAfterEnter: function (el) {
console.log('方块显示动画结束');
},
handleBeforeLeave: function (el) {
console.log('方块隐藏动画即将执行');
},
handleLeave: function (el, done) {
Velocity(el, 'stop');
Velocity(el, {
backgroundColor: '#4dd0e1',
opacity: 0,
translateX: 0,
rotateZ: [0, '360deg']
}, {
duration: 1000,
easing: [ 0.4, 0.01, 0.165, 0.99 ],
complete: done
});
console.log('方块隐藏动画执行中...');
},
handleAfterLeave: function (el) {
console.log('方块隐藏动画结束');
}
}
});
注意:当只用 js动画 过渡的时候,在enter和leave钩子函数中,回调函数done是必须的,否则它们会被同步调用,动画会立即完成(直接跳转到结束状态)
2. 使用元素引用
ref被用来给元素或子组件注册引用信息。 引用信息将会注册在父组件的$refs对象上。如果在普通的 DOM 元素上使用, 引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例
对于一些复杂的多元素动画又不需要状态管理时,在元素上使用ref比较方便(推荐尽量使用第一种钩子函数方式,Vue 中不鼓励直接操作 dom)
修改下上面示例的代码,让方块做一个向右移动并旋转的动画:
HTML
<div id="app">
<div class="rect" ref="rect"></div>
</div>
直接在动画元素上增加一个ref属性
JavaScript
var vm = new Vue({
el: '#app',
mounted: function() {
Velocity(this.$refs.rect, {
backgroundColor: '#0085eb',
translateX: 260,
rotateZ: '360deg'
}, {
duration: 1000,
easing: [ 0.4, 0.01, 0.165, 0.99 ]
});
}
});
因为ref本身是作为渲染结果被创建的, 在初始渲染时获取不到它们,所以动画的代码必须放在 生命周期函数mounted中, 在 Vue 的实例挂载到 dom 时再执行)这里的this.$refs.rect就指向<div ref="rect">