1、多个元素或者组件的过渡动画效果
1.1、多个元素的过渡动画
1、如下例所示我们做的一个例子是点击按钮,在两个不同元素之间切换的的过渡动画。注意的地方有两点
(1)多个元素每一个都需要key值:因为DOM复用的原因,需要不同的key值来标识不同的元素。
(2)transition标签上的mode的属性值会有不同的效果:在下面的例子中,使用mode=“out-in”,效果是这样,hello world渐渐消失,然后在hello world的原地方渐渐出现bye world。而使用mode=“in-out”,效果是这样:在hello world的下一行,先渐渐出现bye world,然后hello world渐渐消失,消失的一瞬间,bye world从第二行窜到了第一行。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>多个元素的过渡</title>
<script src="./vue.js"></script>
<style type=text/css>
.v-enter , .v-leave-to {
opacity: 0;
}
.v-enter-active , .v-leave-active {
transition: opacity 2s;
}
</style>
</head>
<body>
<div id="root">
<transition mode="out-in">
<!--1、当我们不使用key的时候没有动画,因为DOM复用-->
<div v-if="show" key="hello">hello world</div>
<div v-else key="bye">Bye world</div>
</transition>
<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>
1.2、多个组件的过渡动画
1、多个组件的过渡动画注意的就只有一点:在动态组件外层包裹一个transition就行了,模式使用mode去控制就行。如下例:和我们之前在动态组件中使用的代码是一样的。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>多个组件的过渡</title>
<script src="./vue.js"></script>
<style type=text/css>
.v-enter , .v-leave-to {
opacity: 0;
}
.v-enter-active , .v-leave-active {
transition: opacity 2s;
}
</style>
</head>
<body>
<div id="root">
<transition mode="in-out">
<component :is="type"></component>
</transition>
<button @click="handleClick">toggle</button>
</div>
<script>
Vue.component('child',{
template:'<div>child</div>'
});
Vue.component('child-one',{
template:'<div>child-one</div>'
})
var vm = new Vue({
el: "#root",
data: {
type: 'child',
},
methods: {
handleClick: function() {
this.type = this.type === 'child'?'child-one':'child';
}
}
})
</script>
</body>
</html>
2、列表过度
1、列表过渡其实需要注意两点:
(1)给列表的显示元素添加<transition-group>标签。
(2)当我们给列表显示元素添加<transition-group>标签后,其实真正在DOM中是这样的:每个列表元素都被包裹了<transition>标签
<transition>
<div>...</div>
</transition>
<transition>
<div>...</div>
</transition>
<transition>
<div>...</div>
</transition>
...
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>列表的过渡动画</title>
<script src="./vue.js"></script>
<style type=text/css>
.v-enter , .v-leave-to {
opacity: 0;
}
.v-enter-active , .v-leave-active {
transition: opacity 2s;
}
</style>
</head>
<body>
<div id="root">
<!--1、给列表的显示项添加tiansition-group整个外部标签-->
<transition-group>
<div v-for="(item,index) in list" :key="item.id">{{item.text}}</div>
</transition-group>
<button @click="handleClick" >toggle</button>
<button @click="handleDelete">delete</button>
</div>
<script>
var vm = new Vue({
el: "#root",
data: {
list: [],
count: 0,
},
methods: {
handleClick: function() {
count = this.count++;
this.list.push({text:"hello world",id:count});
},
handleDelete: function() {
this.list.pop();
}
}
})
</script>
</body>
</html>
3、动画封装
3.1、使用css过度动画进行封装
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>动画封装</title>
<script src="./vue.js"></script>
<style>
.v-enter , .v-leave-to {
opacity: 0;
}
.v-enter-active , .v-leave-active {
transition: opacity 2s;
}
</style>
</head>
<body>
<div id="root">
<fade :show="show">
<div>hello world</div>
</fade>
<button @click="handleBtnClick">toggle</button>
</div>
<script>
//1、对动画进行简单的封装,特别注意在slot当中只能使用v-if,不能使用v-show
Vue.component('fade',{
props:['show'],
template:`
<transition>
<slot v-if="show"></slot>
</transition>
`
})
var vm = new Vue({
el: "#root",
data: {
show: false,
},
methods: {
handleBtnClick: function() {
this.show = !this.show;
}
}
})
</script>
</body>
</html>
3.2、使用JS动画封装
1、使用JS来封装动画,这种方式是比较推荐的,因为将方法都放在一个组件当中。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>动画封装</title>
<script src="./vue.js"></script>
</head>
<body>
<div id="root">
<fade :show="show">
<div>hello world</div>
</fade>
<button @click="handleBtnClick">toggle</button>
</div>
<script>
//JS动画封装进一个组件中(推荐)
Vue.component('fade',{
props:['show'],
template:`
<transition
@before-enter="handleBeforeEnter"
@enter="handleEnter"
>
<slot v-if="show"></slot>
</transition>
`,
methods: {
handleBeforeEnter: function(el) {
el.style.color = 'red';
},
handleEnter: function(el,done) {
setTimeout(()=>{
el.style.color = 'green';
done();
},2000)
}
}
})
var vm = new Vue({
el: "#root",
data: {
show: false,
},
methods: {
handleBtnClick: function() {
this.show = !this.show;
}
}
})
</script>
</body>
</html>
1、关于动画的东西还有动态过度和状态过度。我们将在之后学习。