Лучше всего абстрагировать всю эту логику c в один компонент для отображения дат, а не запускать обновления через границы кода. Сохраняйте весь код рендеринга даты как можно более минимальным, чтобы можно было легко изменить логи рендеринга даты c в любое время.
Сама дата является данными, но визуальное представление этой даты - нет. Поэтому я не буду хранить отформатированную дату в магазине Vuex.
Создайте компонент <from-now>
, который принимает date
в качестве реквизита и отображает дату, используя момент fromNow
. Он также периодически обновляет себя (каждую минуту). Поскольку это компонент, вы можете отобразить полную дату в виде всплывающей подсказки, чтобы пользователи могли знать точное время, когда на нее наведут курсор.
const components = new Set();
// Force update every component at the same time periodically
setInterval(() => {
for (const comp of components) {
comp.$forceUpdate();
}
}, 60 * 1000);
Vue.component('FromNow', {
template: '<span :title="title">{{ text }}</span>',
props: ['date'],
created() {
components.add(this);
},
destroyed() {
components.remove(this);
},
computed: {
text() {
return moment(this.date).fromNow();
},
title() {
return moment(this.date).format('dddd, MMMM Do YYYY, h:mm:ss a');
},
},
});
new Vue({
el: '#app',
data: {
// Test various seconds ago from now
dates: [5, 60, 60 * 5, 60 * 60].map(sec => moment().subtract(sec, 'seconds')),
},
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
<div id="app">
<p v-for="date of dates">
<from-now :date="date"></from-now>
</p>
</div>
Ради простоты <from-now>
отображает только относительные даты. Я использую аналогичный компонент для этого, но более общего назначения. Требуется format
опора, которая позволяет мне выбрать способ отображения даты (это может быть относительное время или конкретный c формат даты, который принимает этот момент).