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 并设置animation
或transition
来明确声明你需要 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>
多维表格重排
<!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>