简体   繁体   English

Vue.js:更改后的计算属性不会呈现

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM