这是我与VueJS有关的第二个问题。我将问题分为两部分。
1。为什么VueJS方法不断被调用或在循环中运行? 我认为startTimer()将在加载时被调用一次。每当我在数组中推送新的提醒时,它就会不断被调用并冻结浏览器。我想我不了解VueJS中的方法,谁能详细阐述?
2。如何更新数据数组(项目)中单个列表项目的计时器/计数器? 为了跟踪计时器和计数器,我在代码笔中看到了在数据数组(项目)中创建的元素。
<div id="reminders">
<form v-on:submit.prevent="addReminder">
<label for="new-reminder">Reminder</label>
<input v-model="newReminder" type="text" id="new-reminder" placeholder="Feed the cat">
<label for="new-timer">Time</label>
<input v-model="newTimer" type="number" id="new-timer" placeholder="Time in minute">
<button>Add</button>
</form>
<ul>
<li v-for="item,index in items" class="reminder" v-bind:id='"reminder_"+item.id' v-bind:load="startTimer(index)">
{{ item.id }}<span class="title">{{ item.title }}</span>
TIMER: <span class="time">{{ item.time }}</span><br>
COUNTER:<span class="counter">{{ item.counter }}</span><br>
<button class="close" v-on:click="removeReminder(index)"><img src="https://image.flaticon.com/icons/svg/53/53804.svg" alt=""></button>
</li>
</ul>
</div>
var reminder = new Vue({
el: '#reminders',
data: {
newReminder: '',
newTimer: 0,
items: []
},
methods: {
addReminder: function() {
this.items.push({
id: this.items.length,
title: this.newReminder,
time: this.newTimer,
counter:0
})
},
removeReminder: function(index) {
this.items.splice(index, 1);
},
startTimer: function(index) {
if(this.items[index].counter<100)this.items[index].counter++; // if I don't do this. browser will freez and crash after sometime
console.log(this.items[index].counter);
}
}
});
带计时器和计数器的备用代码-
var reminder = new Vue({
el: '#reminders',
data: {
newReminder: '',
newTimer: 0,
items: []
},
methods: {
addReminder: function() {
this.items.push({
id: this.items.length,
title: this.newReminder,
time: this.newTimer,
counter:0
})
},
removeReminder: function(index) {
this.items.splice(index, 1);
},
startTimer: function(index) {
let item = this.items[index];
let t = 0;
function timeout() {
setTimeout(function() {
if (t == item.time * 60) {
$('#' + index).find('.title').css('text-decoration', 'line-through');
} else {
timeout();
item.counter = t++;
$('#' + index).find('.counter').text(item.time * 60 - item.counter);
}
}, 1000);
}
timeout();
}
}
});
答案 0 :(得分:1)
我认为当元素安装到dom时,我们不能使用 v-bind:load 来触发。您可以通过删除v-bind:load来解决问题,但可以在addTimer方法内触发 this.startTimer(this.items.length-1)。
您应该使用Vue.set(this.items,index,counter ++);
答案 1 :(得分:1)
因此,我通过按照@Dat Tran建议修改代码而进行了一点点修改,从而解决了我的示例,并且该代码有效。任何正在研究此问题的人,此解决方案可能对他们有用。
var reminder = new Vue({
el: '#reminders',
data: {
newReminder: '',
newTime: 0,
items: []
},
methods: {
addReminder: function() {
let reminder = {
id: this.items.length,
title: this.newReminder,
time: this.newTime,
counter:0
};
Vue.set(this.items,this.items.length,reminder);
this.startTimer(this.items.length-1);
},
removeReminder: function(index) {
this.items.splice(index, 1);
},
startTimer: function(index) {
setTimeout(()=> {
console.log(this.items);
if ( this.items[index].counter == parseInt(this.items[index].time)*60) {
$('#reminder_' + index).find('.title').css('text-decoration', 'line-through');
} else {
this.startTimer(index);
this.items[index].counter++;
console.log(this.items[index].counter);
$('#reminder_' + index).find('.counter').text(this.items[index].time * 60 - this.items[index].counter);
}
}, 1000);
}
}
});