[英]Vue.js: Changed computed properties don't get rendered
Template: 模板:
<tbody>
<tr v-for="item in transactionList"
v-bind:class="{ 'almost-due': item.time_remaining != null && item.time_remaining < 60 }"
data-transaction="${ item.id }">
<td>${ item.id }</td>
<td>${ item.label }</td>
<td class="text-center minimal">${ item.status_label }</td>
<td class="text-center minimal">
<div v-if="item.time_remaining != null">
<span>${ item.time_remaining * 1000 | moment 'mm:ss' }</span>
</div>
<div v-if="item.time_remaining == null">
${ item.created_at_formatted }
</div>
</td>
</tr>
</tbody>
Script: 脚本:
var Page = new Vue({
el: '#app',
data: {
transactions: [],
now: Date.now() / 1000
},
computed: {
transactionList: {
cache: false,
get: function () {
return this.transactions.map(function (transaction) {
// Calculate remaining time only if there is a due time
if (transaction.assignment_due_at != null) {
// remaining time = due time - now
transaction.time_remaining = Math.floor(
(new Date(transaction.assignment_due_at)).getTime() / 1000
- Page.now
);
} else {
transaction.time_remaining = null;
}
return transaction;
});
}
}
},
created: function () {
setInterval(function () {
Page.$data.now = Date.now() / 1000;
}, 1000);
}
});
Problem is Vue doesn't see that transaction.time_remaining
has changed, thus doesn't update DOM. 问题是Vue看不到
transaction.time_remaining
已更改,因此不会更新DOM。
I use Chrome DevTools Vue plugin, and it confirms that transaction.time_remaining
is updated every second, but I don't see anything change on the page. 我使用了Chrome DevTools Vue插件,它可以确认
transaction.time_remaining
每秒更新一次,但是页面上没有任何变化。
It looks like you have the data property time
in stead of now
in the created
function 看起来在
created
函数中您具有数据属性time
而不是now
Try: 尝试:
created: function () {
setInterval(function () {
Page.$data.now = Date.now() / 1000;
}, 1000);
}
Alright, I solved it. 好吧,我解决了。 I created a
Transaction
component, 我创建了一个
Transaction
组件,
<script> /* Javascript */
var Transaction = Vue.extend({
template: '#transaction-item-template',
props: {
model: Object
},
computed: {
time_remaining: function () {
if (this.model.assignment_due_at == null) {
return null;
}
return Math.max(0, Math.floor(
(new Date(this.model.assignment_due_at)).getTime() / 1000
- Page.now
))
}
}
});
</script>
<script type="text/x-template" id="transaction-item-template"> /* Template */
<tr :class="{ 'almost-due': time_remaining != null && time_remaining < 60 }"
data-transaction="${ model.id }">
<td>${ model.id }</td>
<td>${ model.label }</td>
<td class="text-center minimal">${ model.status_label }</td>
<td class="text-center minimal">
<div v-if="time_remaining != null">
<span>${ time_remaining * 1000 | moment 'mm:ss' }</span>
</div>
<div v-if="time_remaining == null">
${ model.created_at_formatted }
</div>
</td>
</tr>
</script>
And I changed the Vue instance, 我更改了Vue实例,
var Page = new Vue({
el: '#app',
data: {
transactions: [],
now: Date.now() / 1000
},
methods: {
addTransaction: function (transaction) {
this.transactions.unshift(transaction);
},
updateTransaction: function (transaction) {
var index = _.findIndex(this.transactions, {id: transaction.id});
if (index > -1) {
this.transactions.$set(index, transaction);
} else {
this.transactions.push(transaction);
}
}
},
components: {
'transaction': Transaction
},
created: function () {
init();
}
});
function init() {
setInterval(function () {
Page.now = Date.now() / 1000;
}, 1000);
}
And finally, HTML became this, 最后,HTML变成了这个,
<tbody>
<tr is="transaction" v-for="item in transactions" :model="item"></tr>
</tbody>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.