一、多元素过渡
1.多元素过渡
当切换展示的元素标签名相同时,需要给每一个元素设置不同的key值,否则Vue为了效率只会替换相同标签内部的内容。
<template>
<div class="demo">
<button @click="show = !show">click</button>
<transition>
<div v-if="show" key="world">hello world</div>
<div v-else key="shanshan">hello shanshan</div>
</transition>
</div>
</template>
<script>
export default {
data () {
return {
show: true
}
}
}
</script>
<style scoped>
.v-enter,
.v-leave-to {
opacity: 0;
}
.v-enter-active,
.v-leave-active {
transition: all .3s;
}
.v-enter-to,
.v-leave {
opacity: 1;
}
</style>
在一些场景中,可以通过给同一个元素的key值设置不同的状态来替代 v-if 和 v-else。如:
<template>
<div class="demo">
<button @click="handleClick">click</button>
<transition>
<div :key="keyName">hello {
{ keyName }}</div>
</transition>
</div>
</template>
<script>
export default {
data () {
return {
keyName: 'world'
}
},
methods: {
handleClick () {
const isWorld = this.keyName === 'world';
this.keyName = isWorld ? 'shanshan' : 'world';
},
},
}
</script>
<style scoped>
.v-enter,
.v-leave-to {
opacity: 0;
}
.v-enter-active,
.v-leave-active {
transition: all .3s;
}
.v-enter-to,
.v-leave {
opacity: 1;
}
</style>
2.过渡模式
Vue提供一个一个 mode 特性,可以给多个元素过渡应用不同的模式,mode 的值可为:
- in-out:新元素先进行过渡,完成之后当前元素过渡离开。
- out-in:当前元素先进行过渡,完成之后新元素过渡进入。
<template>
<div class="demo">
<button @click="handleClick">click</button>
<transition
mode="out-in"
>
<div :key="keyName">hello {
{ keyName }}</div>
</transition>
</div>
</template>
<script>
export default {
data () {
return {
keyName: 'world'
}
},
methods: {
handleClick () {
const isWorld = this.keyName === 'world';
this.keyName = isWorld ? 'shanshan' : 'world';
},
},
}
</script>
<style scoped>
.v-enter,
.v-leave-to {
opacity: 0;
}
.v-enter-active,
.v-leave-active {
transition: all .3s;
}
.v-enter-to,
.v-leave {
opacity: 1;
}
</style>
3.多组件过渡
我们可以使用动态组件切换展示不同的组件。
//App.vue
<template>
<div id="app">
<base-level >
</base-level>
</div>
</template>
<script>
import BaseLevel from './components/demo';
export default {
name: 'App',
components: {
BaseLevel
},
}
</script>
//demo
<template>
<div class="demo">
<button @click="handleClick">click</button>
<transition mode="in-out" >
<component :is="cmpName"></component>
</transition>
</div>
</template>
<script>
import Demo1 from './demo-1';
import Demo2 from './demo-2';
export default {
components: {
Demo1,
Demo2
},
data () {
return {
cmpName: 'demo1',
}
},
methods: {
handleClick () {
const isDemo1 = this.cmpName === 'demo1';
this.cmpName = isDemo1 ? 'demo2' : 'demo1';
},
},
}
</script>
<style scoped>
.demo {
margin-left: 100px;
}
button {
display: block;
}
.v-enter,
.v-leave-to {
opacity: 0;
transform: translateX(80px);
}
.v-enter-active,
.v-leave-active {
transition: all .3s;
}
.v-enter-to {
opacity: 1;
transform: translateX(0px);
}
.v-leave {
opacity: 1;
transform: translateX(0px);
}
.v-leave-to {
opacity: 0;
transform: translateX(-80px);
}
</style>
//demo-1
<template>
<div class="demo-1">
5-1
</div>
</template>
<style scoped>
.demo-1 {
position: absolute;
display: inline-block;
width: 150px;
height: 30px;
margin-top: 10px;
line-height: 30px;
text-align: center;
background-color: gray;
color: #fff;
}
</style>
//demo-2
<template>
<div class="demo-2">
5-2
</div>
</template>
<style scoped>
.demo-2 {
position: absolute;
display: inline-block;
width: 150px;
height: 30px;
margin-top: 10px;
line-height: 30px;
text-align: center;
background-color: gray;
color: #fff;
}
</style>