前端框架vue.js系列(11):元素动画过渡效果

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.youkuaiyun.com/zeping891103/article/details/78140483

Vue 在插入、更新或者移除 DOM 时,提供多种不同方式的应用过渡效果。它们包括:

(1)在CSS过渡和动画中自动应用 class

(2)配合使用第三方 CSS 动画库,引入animate.css实现效果过渡

(3)配合使用第三方 JavaScript 动画库,引入velocity.js实现效果过渡

(4)引入tween.js数值实现数值过渡


在CSS过渡和动画中自动应用 class

Vue 提供了 transition 的封装组件,在下列情形中,可以给任何元素和组件添加 entering/leaving 过渡。也就是说,使用这种方法实现过渡效果,需要将实现效果的标签放到<transition ></transition>内。当插入或删除包含在 transition 组件中的元素时,Vue 将会做以下处理:
1. 自动嗅探目标元素是否应用了 CSS 过渡或动画,如果是,在恰当的时机添加/删除 CSS 类名。
2. 如果过渡组件提供了 JavaScript 钩子函数,这些钩子函数将在恰当的时机被调用。
3. 如果没有找到 JavaScript 钩子并且也没有检测到 CSS 过渡/动画,DOM 操作 (插入/删除) 在下一帧中立即执行。(注意:此指浏览器逐帧动画机制,和 Vue 的 nextTick 概念不同)

参考Demo:

<style>
	.fade-enter-active,
	.fade-leave-active {
		transition: opacity .5s/*transition用法:属性值  时长。表示某属性值变化过程所需时长*/
	}
	
	.fade-enter,
	.fade-leave-to {
		opacity: 0
	}
</style>

<div id="app">
	<button v-on:click="show = !show">
    			Toggle
  			</button>
	<transition name="fade">
		<p v-if="show">大家好,这里是过渡动画测试</p>
	</transition>
</div>

<script>
	var vue = new Vue({
		el: "#app",
		data: {
			show: true
		}
	});
</script>
点击按钮即可看到过渡效果。

(注)从上面例子可看到<transition name="fade">定义了name为'fade',这个'fade'的作用在于命名过渡动画样式,如上例子中的样式.fade-?-?。这是这种过渡效果的命名规则。在进入/离开的过渡中,会有 6 个 class 切换:

.name-enter:定义进入过渡的开始状态,在元素被插入时生效,在下一个帧移除。
.name-enter-active:定义过渡的状态。在元素整个过渡过程中作用,这个类可以被用来定义过渡的过程时间,延迟和曲线函数。
.name-enter-to: 2.1.8版及以上,定义进入过渡的结束状态。在元素被插入一帧后生效。
.name-leave: 定义离开过渡的开始状态,在离开过渡被触发时生效,在下一个帧移除。
.name-leave-active:定义过渡的状态。在元素整个过渡过程中作用,在离开过渡被触发后立即生效,这个类可以被用来定义过渡的过程时间,延迟和曲线函数。
.name-leave-to: 2.1.8版及以上 定义离开过渡的结束状态。在离开过渡被触发一帧后生效 (于此同时 v-leave 被删除)。
上例中的运行过程如图所示:


引入animate.css实现效果过渡

这种方法需要引用animate.css,百度上搜一下即可下载。它在进入/离开的过渡中,也会有 6 个 状态切换,与上一种类似:

enter-class
enter-active-class
enter-to-class (2.1.8+)
leave-class
leave-active-class
leave-to-class (2.1.8+)

参考Demo:

<link href="https://cdn.jsdelivr.net/npm/animate.css@3.5.1" rel="stylesheet" type="text/css">

<!-- animate.css过渡,地址:https://daneden.github.io/animate.css/ -->
<div id="animatecss">
	<button @click="show = !show">
    			Toggle render
  			</button>
	<transition name="custom-classes-transition" enter-active-class="animated bounceInDown" leave-active-class="animated bounceOutRight">
		<p v-if="show">hello</p>
	</transition>
</div>

<script>
	var animatecss = new Vue({
		el: '#animatecss',
		data: {
			show: true
		}
	})
</script>
(注)所包含的动画效果可以到animate.css官网查看。

引入velocity.js实现效果过渡

通过使用transition的钩子函数监听,监听状态类别如下:
<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>

参考Demo:

<script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.3/velocity.min.js"></script>

<!-- velocity过渡 -->
<div id="velocityjs">
	<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>

<br />
<!-- velocity数组过渡 -->
<div id="staggered-list-demo">
	<input v-model="query">
	<transition-group name="staggered-fade" tag="ul" v-bind:css="false" v-on:before-enter="beforeEnter" v-on:enter="enter" v-on:leave="leave">
		<li v-for="(item, index) in computedList" v-bind:key="item.msg" v-bind:data-index="index">{{ item.msg }}</li>
	</transition-group>
</div>

<script>
	var velocity = new Vue({
		el: '#velocityjs',
		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
				})
			}
		}
	})

	var velocity2 = new Vue({
		el: '#staggered-list-demo',
		data: {
			query: '',
			list: [{
					msg: 'Bruce Lee'
				},
				{
					msg: 'Jackie Chan'
				},
				{
					msg: 'Chuck Norris'
				},
				{
					msg: 'Jet Li'
				},
				{
					msg: 'Kung Fury'
				}
			]
		},
		computed: {
			computedList: function() {
				var vm = this
				return this.list.filter(function(item) {
					return item.msg.toLowerCase().indexOf(vm.query.toLowerCase()) !== -1
				})
			}
		},
		methods: {
			beforeEnter: function(el) {
				el.style.opacity = 0
				el.style.height = 0
			},
			enter: function(el, done) {
				var delay = el.dataset.index * 150;
				setTimeout(function() {
					Velocity(
						el, {
							opacity: 1,
							height: '1.6em'
						}, {
							complete: done
						}
					)
				}, delay)
			},
			leave: function(el, done) {
				var delay = el.dataset.index * 150
				setTimeout(function() {
					Velocity(
						el, {
							opacity: 0,
							height: 0
						}, {
							complete: done
						}
					)
				}, delay)
			}
		}
	});
</script>

引入tween.js数值实现数值过渡

这种过渡效果是:当数字变化时,有一个动态的数字滚动效果。

参考Demo:

<script src="https://cdn.jsdelivr.net/npm/tween.js@16.3.4"></script>

<!-- tween.js数值过渡 -->
<div id="numDemo">
	<label>{{animatedNumber}}</label>
	<button @click="numChange">改变数值</button>
</div>

<script>
	var num = new Vue({
		el: '#numDemo',
		data: {
			animatedNumber: 0
		},
		methods: {
			numChange: function() {
				var vm = this;
				var oldValue = parseInt(this.animatedNumber);
				var newValue = parseInt(this.animatedNumber) + 999;

				function animate() {
					if(TWEEN.update()) {
						requestAnimationFrame(animate)
					}
				}
				new TWEEN.Tween({
						tweeningNumber: oldValue
					})
					.easing(TWEEN.Easing.Quadratic.Out)
					.to({
						tweeningNumber: newValue
					}, 500)
					.onUpdate(function() {
						vm.animatedNumber = this.tweeningNumber.toFixed(0)
					})
					.start();
				animate();
			}
		}
	});
</script>


转载于:https://my.oschina.net/u/3987720/blog/2962720

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值