vue 使用key属性实现多元素过渡
1.代码
由于和一个元素过渡代码只有一点点不同,直接贴代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue多元素过渡</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<style>
p{
transform-origin: 0 50%;
position: relative;
}
.mytr-enter,.mytr-leave-to{
opacity: 0;
}
.mytr-enter-active{
opacity: 1;
animation: first 1s linear;
}
.mytr-leave-active{
opacity: 1;
animation: second 1s linear;
}
@keyframes first{
0% {
transform:scale(0);
}
50% {
transform:scale(1.2,1.2);
}
100% {
transform:scale(1);
}
}
@keyframes second{
0% {
transform:scale(1);
}
40% {
transform:rotate(45deg);
}
55% {
transform:rotate(90deg);
}
85% {
transform:rotate(45deg);
}
100% {
transform:rotate(90deg);
}
}
</style>
</head>
<body>
<div id="app">
<button v-on:click="show=!show">点击</button>
<transition name="mytr" mode="out-in">
<p v-if="show" key="sa">if there is a will, there is a way</p>
<p v-else key="ta">If there is a will, there are ways</p>
</transition>
</div>
<script>
new Vue({
el : '#app',
data : {
show : true
}
})
</script>
</body>
</html>
2.关键代码分析
(1)如果没有设置key特性,那么点击按钮,页面并不会出现动画效果,只是简单地替换了文字。
(2)设置了key特性,没有设置 mode,那么一个元素的出现动画和另外一个元素的消失动画会同时在页面上面进行,看起来比较混乱。
(3)设置了key特性,也设置 mode,出现动画和消失动画会按顺序执行
,效果正常
(4)mode取值
out-in
:先让元素消失,然后让另一个元素出现。
in-out
:先让元素出现,然后让另一个元素消失。
3.原因分析
Vue在多个元素切换过程中会尽量复用DOM,如果不加key,那么vue会选择复用节点(Vue的就地更新策略),导致之前节点的状态被保留下来,由此产生一系列的bug。所以需要通过 key 特性设置唯一的值来标记以让 Vue 区分它们,否则 Vue 为了效率只会替换相同标签内部的内容。