javascript - 如何摆脱部分CSS动画在Vuejs中更新v-for渲染列表顺序后重新启动
问题描述
我有一个数据列表,模板将使用这个列表来绘制包含每个时间栏的块列表。
列表的顺序可以随时更新,我发现每次更新列表顺序时,都会意外重启一些时间条动画。
这是模拟行为的jsFiddle,有人可以建议我摆脱它的解决方案吗?谢谢!
JsFiddle 代码:
https://jsfiddle.net/tklfiddle/30z4km8f/7/
Vue 模板
<div id="app">
<h2>TimeBars:</h2>
<button @click="reOrder">
Shuffle
</button>
<ul class="listWrapper">
<li v-for="(item, index) in list" class="row itemTest" :id="item.id" :key="item.id">
<div class="timeBarContainer">
<div class="timeBar" :style="{animationDuration: item.duration+ 's'}">
</div>
<div class="timeBarText">
{{item.id}}
</div>
</div>
</li>
</ul>
{{list}}
</div>
JS
new Vue({
el: "#app",
data: {
list: [
{ id: "bar1", done: false, duration: 10 },
{ id: "bar2", done: false, duration: 10 },
{ id: "bar3", done: true, duration: 10 },
{ id: "bar4", done: true, duration: 10 }
]
},
mounted(){
console.log("DEBUG: mounted", $("body"));
$(".listWrapper").on('DOMNodeRemoved', function(e) {
console.log(e.target, ' was removed');
});
},
methods: {
reOrder: function(){
this.list = shuffle(this.list);
//this.list.pop();
console.log("DEBUG: this.list:", JSON.stringify(this.list));
function shuffle(array) {
var currentIndex = array.length, randomIndex;
// While there remain elements to shuffle...
while (0 !== currentIndex) {
// Pick a remaining element...
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex--;
// And swap it with the current element.
[array[currentIndex], array[randomIndex]] = [
array[randomIndex], array[currentIndex]];
}
return JSON.parse(JSON.stringify(array));
}
}
}
})
SCSS
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
#app {
background: #fff;
border-radius: 4px;
padding: 20px;
transition: all 0.2s;
}
li {
margin: 8px 0;
>div{
display: inline-block;
}
}
h2 {
font-weight: bold;
margin-bottom: 15px;
}
.timeBarContainer{
width: 100%;
height: 15px;
position: relative;
}
.timeBar{
width: 100%;
height: 100%;
background-color: red;
float: right;
animation: timeBarAnimation 0s linear normal forwards;
}
.timeBarText{
position: absolute;
}
@keyframes timeBarAnimation {
0% {
width: 100%;
}
100% {
width: 0;
}
}
CodeSandBox 代码:
这是另一个使用 codeSandBox 编码的示例,正如您所见,TimeBar 组件在洗牌后没有被卸载,但 css 动画正在重新启动,这是意外的。
https://codesandbox.io/s/great-smoke-n806b?file=/src/components/TimeBar.vue
解决方案
我希望这可以帮助你:
当您通过直接设置索引(例如 arr[0] = val)或修改其长度属性来修改数组时。同样,Vue.js 无法接受这些更改。始终使用 Array 实例方法或完全替换它来修改数组。Vue 提供了一个方便的方法 arr.$set(index, value),它是 arr.splice(index, 1, value) 的语法糖。
推荐阅读
- java - TCP Client socket 挂了 Server Socket
- sql - 删除 ORACLE 服务器中的保存点
- sql-server - Entity Framework 6 Code First - 与不同数据库的关系
- node.js - ApolloClient 不是构造函数(apollo-client with nodejs)
- javascript - 如何在 SAPUI5 中动态地将样式应用于标签元素
- python - 带反转法的真值评估链法
- python - 根据行数拆分 JSON 文件
- ruby - 试图将枚举放入 rails 5 中的选择表单助手类
- mysql - recover a mysql-db from time-machine on a mac
- php - Laravel relationships confusion