VUE学习-元素过渡

单元素过渡

appear 初始渲染

通过 appear attribute 设置节点在初始渲染的过渡

  • appear + 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>
    
  • appear + js钩子

    <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-show 条件显示或者动态组件下可以添加进入/离开过渡

<div id="demo">
	<button v-on:click="show = !show">Toggle</button>
	<transition name="fade">
		<p v-if="show">hello</p>
	</transition>
</div>
<script>
new Vue({
	el: '#demo',
	data: {show: true }
})
</script>
<style>
/* 定义进入 /离开的过渡动作 */
.fade-enter-active, .fade-leave-active {transition: opacity .5s;}
/* .fade-leave-active below version 2.1.8 */
.fade-enter, .fade-leave-to {opacity: 0;}
</style>

动画

CSS 动画用法同 CSS 过渡,区别是在动画中 v-enter 类名在节点插入 DOM 后不会立即删除,而是在 animationend 事件触发时删除。

<div id="demo">
	<button v-on:click="show = !show">Toggle</button>
	<transition name="bounce">
		<p v-if="show">hello</p>
	</transition>
</div>
<script>
new Vue({
	el: '#demo',
	data: {show: true }
})
</script>
<style>
/* 定义进入 / 离开的动画 */
.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);}
}
</style>

在一些场景中,你需要给同一个元素同时设置两种过渡动效,比如 animation 很快的被触发并完成了,而 transition 效果还没结束。在这种情况中,你就需要使用 type attribute 并设置 animationtransition 来明确声明你需要 Vue 监听的类型。

多元素过渡

  • 多个原生标签可以使用 v-if/v-else:
    最常见的多标签过渡是一个列表和描述这个列表为空消息的元素:

    <transition>
    	<table v-if="items.length > 0">
    		<!-- ... -->
    	</table>
    	<p v-else>Sorry, no items found.</p>
    </transition>
    
  • 相同标签名的元素切换时,需要通过 key attribute 设置唯一的值

    <transition>
    	<button v-if="isEditing" key="save">Save</button>
    	<button v-else key="edit">Edit</button>
    </transition>
    <!-- 也可以通过给同一个元素的 key attribute 设置不同的状态 -->
    <transition>
    	<button v-bind:key="isEditing">{{ isEditing ? 'Save' : 'Edit' }}</button>	</transition>
    
  • 多个组件的过渡可以使用动态组件:

    <div id="comp">
    	<radio v-model="view" value="v-a">A</radio>
    	<radio v-model="view" value="v-b">B</radio>
    	<transition name="component-fade" mode="out-in">
    		<component v-bind:is="view"></component>
    	</transition>
    </div>
    <script>
    new Vue({
    	el: '#transition-components-demo',
    	data: {view: 'v-a'},
    	components: {
    		'v-a': {
    			template: '<div>Component A</div>'
    		},
    		'v-b': {
    			template: '<div>Component B</div>'
    		}
    	}
    })
    </script>
    <style>
    .comp-fade-enter-active, .comp-fade-leave-active {transition: opacity .3s ease;}
    .comp-fade-enter, .comp-fade-leave-to {opacity: 0;}/* .component-fade-leave-active for below version 2.1.8 */
    </style>
    
    
  • 列表过渡

    <div id="list-demo" class="demo">
    	<button v-on:click="add">Add</button>
    	<button v-on:click="remove">Remove</button>
    	<transition-group name="list" tag="p">
    		<span v-for="item in items" v-bind:key="item" class="list-item">{{ item }}</span>
    	</transition-group>
    </div>
    <script>
    new Vue({
    	el: '#list-demo',
    	data: {
    		items: [1,2,3,4,5,6,7,8,9],
    		next: 10
    	},
    	computed:{
    		rIndex: function () {
    			return Math.floor(Math.random() * this.items.length)
    		},
    	},
    	methods: {
    		add: function () {
    			this.items.splice(this.rIndex, 0, this.next++)
    		},
    		remove: function () {
    			this.items.splice(this.rIndex, 1)
    		},
    	}
    })
    </script>
    <style>
    .list-item {
    	display: inline-block;
    	margin-right: 10px;
    	display: inline-block;
    }
    .list-enter-active, .list-leave-active { 
    	transition: all 1s;
    }
    .list-enter, .list-leave-to {
    	opacity: 0;
    	transform: translateY(30px);
    }
    /* .list-leave-active for below version 2.1.8 */
    .list-move {
    	transition: transform 1s;
    }
    </style>
    

多维表格重排

https://codesandbox.io/s/github/vuejs/vuejs.org/tree/master/src/v2/examples/vue-20-list-move-transitions?file=/index.html:0-1157

<!DOCTYPE html>
<html>
<head>
	<title>List Move Transitions Sudoku Example</title>
	<script src="https://unpkg.com/vue@2"></script>
	<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.14.1/lodash.min.js"></script>
	<link rel="stylesheet" type="text/css" href="/style.css" />
</head>
<body>
	<div id="sudoku-demo" class="demo">
		<h1>Lazy Sudoku</h1>
		<p>Keep hitting the shuffle button until you win.</p>
		<button @click="shuffle">Shuffle</button>
		<transition-group name="cell" tag="div" class="container">
			<div v-for="cell in cells" :key="cell.id" class="cell">{{ cell.number }}</div>
		</transition-group>
	</div>
	<script>
	new Vue({
		el: "#sudoku-demo",
		data: {
			cells: Array.apply(null, { length: 81 }).map(function(_, index) {
				return {
					id: index,
					number: (index % 9) + 1
				};
			})
		},
		methods: {
			shuffle: function() {
				//创建一个被打乱值的集合
				this.cells = _.shuffle(this.cells);
			}
		}
	});
	</script>
</body>
</html>
posted @ 2022-08-13 14:40  ~LemonWater  阅读(80)  评论(0编辑  收藏  举报