vue.js中的过渡动画效果(transition+animate.css+velocity.js)

对于“数据优先”的Vue来说,没有了dom的操作,过渡效果该如何实现?

其实,vue也不是完全失去了对dom的操作,仍然可以通过比如$refs获取对应的dom元素


先看一个小demo:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script>
	</head>
	<body>
		<div id="root">
			<div v-show="show">Hello world</div> 
			<button @click="handleClick">toggle</button>
		</div>
		<script>
			var vm=new Vue({
				el:'#root',
				data:{
					show:true
				},
				methods:{
					handleClick:function(){
						this.show=!this.show
					}
				}
			})
		</script>
	</body>
</html>

其效果如下:
在这里插入图片描述

但可以看到,其中文字“Hello world”的“行为”非常生硬。一个元素尚且如此,更别说两个元素来回切换的场景了。

为此,vue提供了一个“进出过渡”的特效CSS语法。其使用前要先用<transition></transition> 包裹涉及到的所有标签:
我们来看两个元素的效果——修改上面demo-Hello world部分

<transition>
	<div v-if="show">Hello world</div>
	<div v-else>Bye world</div>
</transition>

保存一下,到页面上看,会发现依然很“不爽”。这可能是因为还没有写style的缘故:

.v-enter,.v-leave-to{   /* 过渡前 */
	opacity:0;
}
.v-enter-active,.v-leave-active{   /* 过渡中 */
	transition:opacity 1s;
}

做完这些我们就会发现。。。效果依然没有出现!
这是为什呢? ——Vue默认会【复用dom】,通俗地说,就是【缓存DOM】。要想解除这个,需要给每个元素加一个key

<transition mode="out-in">
	<div v-if="show" key="key1">Hello world</div>
	<div v-else key="key2">Bye world</div>
</transition>

这样就可以了:
在这里插入图片描述

上面是多个元素的切换,那么多个组件呢?
笔者建议最好采用动态组件的方式:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script>
	</head>
	<body>
		<div id="root">
			<component :is="type"></component>
			<button @click="handleClick">toggle</button>
		</div>
		<script>
			Vue.component('child',{
				template:'<div>Hello world</div>'
			})
			Vue.component('childs',{
				template:'<div>Bye world</div>'
			})
			var vm = new Vue({
				el: '#root',
				data: {
					type:'child'
				},
				methods: {
					handleClick: function() {
						this.type=this.type==='child'?'childs':'child'
					}
				}
			})
		</script>
	</body>
</html>

其实,在真正项目里,很多时候笔者采用的就是这种方法:比如在一个vue多页面(组件)的项目里,页面之间切换时有一个向左/右滑动的效果:

<transition :name="transitionName">
	<router-view class="Router" />
</transition>

//js-data
data(){
	retrun{
		transitionName:'slide-right',
		//...
	}
}
//js-watch
watch:{
	$route(to,from){   //导航发生变化,$route也就是会改变
		if(to.meta.index > from.meta.index){
			this.transitionName:'slide-right'
		}else{
			this.transitionName:'slide-left'
		}
	}
}

//css
.Router{
	position:absolute;
	width:100%;
	transition:all .8s ease;
}
.slide-left-enter,.slide-right-leave-active{
	opacity:0;
	transform:translate(100%,0);
}
.slide-left-leave-active,.slide-right-enter{
	opacity:0;
	transform:translate(-100%,0);
}

这样的话,其app.vue里的路由routes中每一项都要加上一个属性:

meta:{index:数字};

emmmmmm…vue中使用第三方库函数又是另一番体验了:
让我们把目光重新聚焦到本文第一例demo上,看一下animate.css的“风情”:

npm install animate.css
<link rel="stylesheet" href="./animate.css">

<div id="root">
	<transition
			enter-active-class="animated swing"
			leave-active-class="animated shake"
	>
			<div v-show="show">Hello world</div> 
			<button @click="handleClick">toggle</button>
	</transition>
</div>
<script>
	var vm=new Vue({
		el:'#root',
		data:{
			show:true
		},
		methods:{
			handleClick:function(){
				this.show=!this.show
			}
		}
	})
</script>

如上,swing和shake就是animate.css内部封装好的两种负责“抖动”动画的类名。 —— 没错,它的实现原理就是@keyframes


说完了css,不妨再来看看JS:他也可以制造动画效果 —— Velocity.js插件:

npm install velocity.js
<transition
		@before-enter="ha1"
		@enter="ha2"
		@after-enter="ha3"
>
	<div v-show="show">Hello</div>
</transition>

//js-methods
methods:{
	//这些函数会接收一个参数:指向绑定的dom
	ha1:function(el){
		el.style.opacity=0
	},
	ha2:function(el){
		Velocity(el,{opacity:1},{duration:1000,complete:done})
	},
	ha3:function(el){
		alert("动画结束!")
	}
}
发布了193 篇原创文章 · 获赞 464 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/qq_43624878/article/details/104749979