起初我是初学者 我试图为某些项目制作vue.js动画,但效果很好,但我的动画错误了
- 我们有按钮随机添加元素
- 我们可以点击元素将其删除
问题:
- 动画总是在最后一项上运行
我希望vue js应该在添加或删除的项目上应用动画
导致动画出错的代码有什么问题?
我应该更改或添加什么才能使动画正常工作?
new Vue({
el: "#app",
data: {
myNumbers: [1, 2, 3, 4],
highestNumberInMyNumbers: 4
},
methods: {
addNumber() {
this.highestNumberInMyNumbers++;
this.myNumbers.splice(Math.floor(Math.random() * this.myNumbers.length), 0, this.highestNumberInMyNumbers);
},
removeNumber(element) {
this.myNumbers.splice(element, 1)
}
}
})

.mix-enter {
opacity: 0;
}
.mix-enter-active {
transition: opacity 500ms;
animation: mixing-in 600ms ease-in forwards;
}
.mix-leave {}
.mix-leave-active {
transition: opacity 1000ms;
animation: mixing-out 0.4s ease-in forwards;
opacity: 0;
}
@keyframes mixing-in {
from {
transform: translateX(-20px) translateY(20px);
}
to {
transform: translateX(0px) translateY(0px);
}
}
@keyframes mixing-out {
from {
transform: translateX(0px) translateY(0px);
}
to {
transform: translateX(-20px) translateY(-20px);
}
}

<script src="https://vuejs.org/js/vue.min.js"></script>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<div id="app">
<h2>group transition for directive v-for </h2>
<hr>
<button @click="addNumber">Add number</button>
<br>
<br>
<div class="row">
<ul class="col-xs-4 col-sm-4 col-md-4 col-lg-4 col-xs-offset-4">
<transition-group name="mix" mode="out-in">
<li class="alert alert-success list-unstyled" style="height: 40px; padding: 10px 15px;margin-bottom: 8px;cursor: pointer;" v-for="(number,index) in myNumbers" @click="removeNumber(index)" :key="index">{{number}}
</li>
</transition-group>
</ul>
</div>
</div>
&#13;
答案 0 :(得分:21)
transition-group
中存在错误!
当您将key
li
绑定为index
时,每次删除li
时,动画始终会在最后{{1}发生元素。
因此,如果您想将动画与li
一起使用,则可以在案例中将li
与key
绑定。
number
VS
<transition-group name="mix"
mode="out-in">
<li class="alert alert-success list-unstyled"
style="height: 40px; padding: 10px 15px;margin-bottom: 8px;cursor: pointer;"
v-for="(number,index) in myNumbers"
@click="removeNumber(index)"
:key="index">
{{number}}
</li>
</transition-group>
最后,如果您使用<transition-group name="mix"
mode="out-in">
<li class="alert alert-success list-unstyled"
style="height: 40px; padding: 10px 15px;margin-bottom: 8px;cursor: pointer;"
v-for="(number,index) in myNumbers"
@click="removeNumber(index)"
:key="number">
{{number}}
</li>
</transition-group>
动画,请不要将transition-group
与key
绑定,而不是index
或item
(在你的情况)。
无论如何,请确保number
具有唯一值。
答案 1 :(得分:3)
在使用过渡或过渡组时,请勿在 v-bind:key 中的任何位置使用 index 。
vuejs.org上的食谱中有错误/丢失的文档以及不良的文档,但是注释[1]中有关于索引如何工作的详细说明,但没有意识到,这对于开发人员来说是个问题。这是当前状态。
我已经在github上发布了几次,但是那里的Vue.js开发人员充其量似乎不屑一顾,拒绝记录这种行为或将其识别为问题。
下面的代码库中有三个示例。 #1有效,#2使用:key =“ index”(上面您的特定错误),#3使用:key =“ item +'_'+ index”。
#2和#3给出您遇到的错误。
https://codepen.io/megacromulent/pen/wEzWNL
codepen摘要:
这个有效 :(使用项目作为:key)
<transition-group name="fade" tag="ol">
<li v-for="(item, index) in items"
v-bind:key="item">
{{item}}
</li>
</transition-group>
此失败 :(使用索引作为:key)
<transition-group name="fade" tag="ol">
<li v-for="(item, index) in items"
v-bind:key="index" >
{{item}}
</li>
</transition-group>
此问题失败 :(将索引和字符串中的字符串连接在一起)
<transition-group name="fade" tag="ol">
<li v-for="(item, index) in items"
v-bind:key="item + '_' + index" >
{{item}}
</li>
</transition-group>
我在此向Vue.js开发人员提交了此错误报告:
“如果使用索引作为键,过渡组仅对最后一个元素进行动画处理”
https://github.com/vuejs/vue/issues/8718
它立即关闭,因此根据他们的输入(要求我进行PR进行评论,但这不在我的操舵室中),我随后针对此功能提出了要求,要求开发人员创建错误,以解决错误根本原因就是问题。
“在带有v-for和过渡的:key值中使用索引时,Dev构建控制台错误”
https://github.com/vuejs/vue/issues/8730
在这个问题上放一个开发错误似乎很合理,但是vue.js开发人员似乎认为我们应该能够自己解决这个问题。我希望他们过来看看,这是一个真正的问题。这花费了我数小时的测试和报告时间才能弄清楚。
我希望这可以帮助其他开发人员在此问题上浪费时间。
参考
[1] https://github.com/vuejs/vue/issues/8718#issuecomment-416909724
答案 2 :(得分:0)
我针对这种情况的解决方案: 为您的数组创建一个随机生成的字符串,然后使用此随机生成的字符串作为键。
模板
<div v-for="(row, index) in rows" :key="row.randomKey">
...
</div>
脚本
export default {
data() {
return {
rows: [],
}
},
methods: {
add() {
this.rows.push({
id: null,
name: '',
randomKey: this.generateRandomKey()
})
},
remove(index) {
this.currency_exchange.splice(index, 1)
},
generateRandomKey() {
let length = 10
return Math.round((Math.pow(36, length + 1) - Math.random() * Math.pow(36, length))).toString(36).slice(1);
}
}
}
答案 3 :(得分:0)
超大分子
好的研究!
对于那些像我一样来这里寻找的人:
更改键(即删除和创建元素)时,很可能会出现动画,如果键没有更改,则将没有动画。 当数组更改时,所有元素都将重建,这意味着键也将被重写,如果它们在元素上发生更改,这将使元素消失并显示。
超大分子让我们看看:
在第二种情况下,带有索引的选项-我们删除了数组的第一个元素,新键被放置在组件中所有其余元素上-但在开始时它们将是相同的0,1,2。 ..即,第一个列表的键不会更改,因此元素不会被破坏,因此也不会动画。
在第三版中,所有元素的关键点每次都会更改,即,所有元素都将被重绘,即删除并重建后,动画将对所有元素起作用
在第一个版本中。如果项目相同,则它与索引相同,因为键不会更改,这意味着在所有相同的情况下,只有最后一个会被设置为动画,即在向项目添加和删除项目时列表的末尾。