使计算的 Vue 属性依赖于当前时间?

Make computed Vue properties dependent on current time?

我有 collection 个 Events。这些将根据其状态呈现在列表中 - upcoming/live/previous。因此渲染取决于当前时间。随着时间的推移,如何使计算属性变为 update/recompute?

<template>
    <div>
        <h2>Upcoming events</h2>
        <p v-bind:key="event.name" v-for="event in upcomingEvents">{{ event.name }}</p>

        <h2>Live events</h2>
        <p v-bind:key="event.name" v-for="event in liveEvents">{{ event.name }}</p>

        <h2>Previous events</h2>
        <p v-bind:key="event.name" v-for="event in previousEvents">{{ event.name }}</p>
    </div>
</template>

<script>
    import Event from '../Event.js'

    export default {
        data() {
            return {
                events: []
            }
        },

        computed: {
            upcomingEvents() {
                return this.events.filter(event => event.isUpcoming())
            },

            liveEvents() {
                return this.events.filter(event => event.isLive())
            },

            previousEvents() {
                return this.events.filter(event => event.isPrevious())
            },
        },

        mounted() {
            // this.events are populated here 
        }
    }
</script>

您可以声明一个时间相关的数据变量并使用setInterval()更新它:

data() {
    return {
        events: [],
        now: Date.now()
    }
},
created() {
    var self = this
    setInterval(function () {
         self.now = Date.now()
    }, 1000)
},
computed: {
    upcomingEvents() {
        return this.events.filter(event => event.isUpcoming(this.now))
    },
    liveEvents() {
        return this.events.filter(event => event.isLive(this.now))
    },
    previousEvents() {
        return this.events.filter(event => event.isPrevious(this.now))
    }
}

请注意,您需要在计算属性中使用 now 来使它们更新。

您的情况的一种可能性是 $forceUpdate()。但是,应该注意它会专门针对您的情况,因为您没有使用子组件。

如果您要使用子组件,则需要在父组件中使用 slots 并将子组件插入它们各自的插槽中。

因此,例如,您可以这样做:

created() {
    setInterval(() => {
        this.$forceUpdate()
    }, 5000)
}

这将导致整个组件重新渲染。这可能是也可能不是您正在寻找的理想互动。

您可以创建一个每秒更新一次的时间变量,然后在您的计算属性中使用该变量。

new Vue({
  el: "#app",
  data: {
    time: ''
  },
  computed: {
    computedValue: function(){
        return this.time;
    }
  },
  mounted: function(){
    var app = this;
    setInterval(function(){
      app.time = parseInt(new Date().getTime() / 1000);
        }, 1000);
  }
})

https://jsfiddle.net/ecwnvudz/