使计算的 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);
}
})
我有 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);
}
})