动画与过渡

  • 引入场景,先简单展示文字的显示/隐藏效果

    ### Hello.vue
    <template>
    	<div>
    		<button type="button" @click="isShow=!isShow">显示/隐藏</button>
    		<h1 v-show="isShow">你好啊</h1>
    	</div>
    </template>
    
    <script>
    	export default {
    		name:'Hello',
    		data(){
    			return {
    				isShow:true
    			}
    		}
    	}
    </script>
    
    <style>
    	h1 {
    		background: orange;
    	}
    </style>
    
    
  • 简单动画

    ### Hello.vue
    <template>
    	<div>
    		......
    		<!--简单应用go样式-->
    		<h1 v-show="isShow" class="go">你好啊</h1>
    	</div>
    </template>
    
    <script>
    	export default {
    		name:'Hello',
    		data(){
    			return {
    				isShow:true
    			}
    		}
    	}
    </script>
    
    
    <style>
    	h1 {
    		background: orange;
    	}
    	
    	.come{ /*来的效果*/
    		animation: simpleAnimation 1s;
    	}
    	 
    	.go { /*走的效果*/
    		animation: simpleAnimation 1s reverse;
    	}
    	
    	
    	@keyframes simpleAnimation{ /*定义帧*/
    		from{
    			transform: translateX(-100px);
    		}
    		to{
    			transform: translateX(0px);
    		}
    	}
    </style>
    
    
  • 使用vue推荐的方式来实现

    <template>
    	<div>
    		<button type="button" @click="isShow=!isShow">显示/隐藏</button>
    		<!-- <h1 v-show="isShow" class="go">你好啊</h1> -->
    		<transition> <!--transition包裹起来,自动调用下面的css样式-->
    			<h1 v-show="isShow">你好啊</h1>
    		</transition>
    		
    	</div>
    </template>
    
    <script>
    	export default {
    		name:'Hello',
    		data(){
    			return {
    				isShow:true
    			}
    		}
    	}
    </script>
    
    
    <style scoped>
    	h1 {
    		background: orange;
    	}
    	
    	.v-enter-active{ /*动画来的效果*/
    		animation: simpleAnimation 1s;
    	}
    	
    	.v-leave-active{ /*动画走的效果*/
    		animation: simpleAnimation 1s reverse;
    	}
    	
    	/* .come{
    		animation: simpleAnimation 1s;
    	}
    	
    	.go {
    		animation: simpleAnimation 1s reverse;
    	} */
    	
    	
    	@keyframes simpleAnimation{
    		from{
    			transform: translateX(-100px);
    		}
    		to{
    			transform: translateX(0px);
    		}
    	}
    </style>
    
    
  • 也可以给这个动画效果取名

    <template>
    	<div>
    		<button type="button" @click="isShow=!isShow">显示/隐藏</button>
    		<!--取个名字-->
    		<!--:appear="true"表示页面一开始就有动画效果,而不是等用户点击按钮以后才展示动画(可以如下简写)-->
    		<!--<transition name="hello" :appear="true">-->
    		<transition name="hello" appear>
    			<h1 v-show="isShow">你好啊</h1>
    		</transition>
    		
    	</div>
    </template>
    
    <script>
    	export default {
    		name:'Hello',
    		data(){
    			return {
    				isShow:true
    			}
    		}
    	}
    </script>
    
    
    <style scoped>
    	h1 {
    		background: orange;
    	}
    	
    	.hello-enter-active{ /*名字跟着变*/
    		animation: simpleAnimation 1s;
    	}
    	
    	.hello-leave-active{
    		animation: simpleAnimation 1s reverse;
    	}
    	
    	@keyframes simpleAnimation{
    		from{
    			transform: translateX(-100px);
    		}
    		to{
    			transform: translateX(0px);
    		}
    	}
    </style>
    
    
  • 使用vue的另外一种类似的方式(这种称为过度,上面那种称为动画),也可以实现上述效果(新建hello2组件)

    ### hello2.vue
    <template>
    	......
    </template>
    
    <script>
    	......
    </script>
    
    
    <style scoped>
    	h1 {
    		background: orange;
    		transition: 0.5s linear; /*过渡效果*/
    	}
    	
    	/*进入的起点,离开的终点*/
    	.hello2-enter,.hello2-leave-to {
    		transform: translateX(-100px);
    	}
    	/*进入的终点,离开的起点*/
    	.hello2-enter-to,.hello2-leave{
    		transform: translateX(0px);
    	}
    	
    </style>
    
    
  • 过度效果还可以这么写

    ### hello2.vue
    ......
    <style scoped>
    	h1 {
    		background: orange;
    		/* transition: 0.5s linear; */
    	}
    	
    	.hello2-enter,.hello2-leave-to {
    		transform: translateX(-100px);
    	}
    	
    	.hello2-enter-active,.hello2-leave-active{
    		transition: 0.5s linear; /*写在这里*/
    	}
    	
    
    	.hello2-enter-to,.hello2-leave{
    		transform: translateX(0px);
    	}
    	
    </style>
    
    
  • 如果渲染多个子项,可以这么搞

    <template>
    	<div>
    		<button type="button" @click="isShow=!isShow">显示/隐藏</button>
    		<!--使用transition-group包裹,同时必须指定":key"值-->
    		<transition-group name="hello2" appear>
    			<h1 v-show="isShow" :key="1">你好啊,Hi</h1>
    			<h1 v-show="isShow" :key="2">Welcome</h1>
    		</transition-group>
    		
    	</div>
    </template>
    ......
    
  • 上述例子,使用之前的写法也可以

    <template>
    	<div>
    		<button type="button" @click="isShow=!isShow">显示/隐藏</button>
    
    		<!-- <transition-group name="hello2" appear>
    			<h1 v-show="isShow" :key="1">你好啊,Hi</h1>
    			<h1 v-show="isShow" :key="2">Welcome</h1>
    		</transition-group> -->
    		
    		<transition name="hello2" appear>
    			<div v-show="isShow"> <!--使用一个div包裹起来-->
    				<h1>你好啊,Hi</h1>
    				<h1>Welcome</h1>
    			</div>
    		</transition>
    		
    	</div>
    </template>
    
  • 使用第三方库来实现动画效果---animate.css(使用超级简单...)

    // 安装
    npm install animate.css
    
    ### Hello3.vue
    <template>
    	<div>
    		<button type="button" @click="isShow=!isShow">显示/隐藏</button>
    		<transition-group 
    		appear
    		name="animate__animated anmimate__bounce" <!--animate库的使用方法,指定3个属性-->
    		enter-active-class="animate__swing"
    		leave-active-class="animate__backOutUp" >
    			<h1 v-show="isShow" :key="1">你好啊,Third</h1>
    			<h1 v-show="isShow" :key="2">Welcome,Third</h1>
    		</transition-group>
    	</div>
    </template>
    
    <script>
    	import 'animate.css' // 引入
    	export default {
    		name:'Hello3',
    		data(){
    			return {
    				isShow:true
    			}
    		}
    	}
    </script>
    
    
    <style scoped>
    	h1 {
    		background: orange;
    	}
    </style>
    
    
  • Vue封装的过度与动画

    - 作用: 在插入/更新/移除DOM元素时,在合适的时候给元素添加样式类名
    
    - 写法
    
    	- 准备好样式
    	
    		- 元素进入的样式
                - v-enter:进入的起点
                - v-enter-active: 进入过程中
                - v-enter-to: 进入的终点
            - 元素离开的样式
            	- v-leave: 离开的起点
            	- v-leave-active: 离开过程中
            	- v-leave-to: 离开的终点
            	
        - 使用<transition>包裹要过度的元素,并配置name属性
        
            <transition name="hello" appear>
                <h1 v-show="isShow">你好啊</h1>
            </transition>
            
        - 备注: 若有多个元素需要过度,则需要使用 <transition-group>,且每个元素都要指定key值
    		
    

  • todo列表子项,改造成动画效果(写在MyItem.vue)

    <template>
    	<!--使用transition标签包裹起来-->
    	<transition name="todo" appear> 
    		<li>
    			......
    		</li>
    	</transition>
    </template>
    
    <style>
    	.......
    	/*动画效果*/
    	.todo-enter-active{
    		animation: simpleAnimation 1s;
    	}
    	
    	.todo-leave-active{
    		animation: simpleAnimation 1s reverse;
    	}
    	
    	@keyframes simpleAnimation{
    		from{
    			transform: translateX(-100px);
    		}
    		to{
    			transform: translateX(0px);
    		}
    	}
    </style>
    
  • todo列表子项,改造成动画效果(写在MyList.vue)

    <template>
    	<ul class="todo-main">
    		<!--把MyItem组件包裹起来-->
    		<transition-group name="todo" appear>
    			<MyItem  v-for="todoObj in todos"
    			:key="todoObj.id" 
    			:todo="todoObj" />
    		</transition-group>
    		
    		
    	</ul>
    </template>
    ......
    <style>
    	......
    	/*动画效果*/
    	.todo-enter-active{
    		animation: simpleAnimation 1s;
    	}
    	
    	.todo-leave-active{
    		animation: simpleAnimation 1s reverse;
    	}
    	
    	@keyframes simpleAnimation{
    		from{
    			transform: translateX(-100px);
    		}
    		to{
    			transform: translateX(0px);
    		}
    	}
    </style>