Reputation: 1601
How the best way to re-render v-for in my application when I change/move to another route in vue js?
In my case I use vuex
, vuex-persistedstate
and moment
for save localStorage and show a moment ago
time.
But how to use rerender v-for without data changes from my API
and reload page manual?
Recent Activity data always cache in localStorage
. But if no new data from api, how to make this always become 3 minutes ago
then 4 minutes ago
etc....
It happend only if I reload the page. Because my code like
<template>
<div class="widget">
<h4 class="widget-title">Recent Activity</h4>
<ul class="activitiez">
<li v-for="act in recentActivity" :key="act._id" :id="act._id">
<div class="activity-meta">
<i v-html="convertToMoment(act.created_at)"></i>
<span v-html="act.activity"></span>
<h6>by <a href="#" v-html="act.sent_name"></a></h6>
</div>
</li>
</ul>
</div>
</template>
<script>
import {mapGetters, mapActions} from "vuex"
export default {
created() {
this.fetchRecentActivityData()
},
computed: {
...mapGetters(["recentActivity"])
},
methods: {
...mapActions(["fetchRecentActivityData"]),
convertToMoment(data) {
return moment(data).fromNow()
}
},
}
</script>
<style>
</style>
and my store code
import axios from 'axios';
const state = {
recentActivityStore: [],
errorBag: null,
timingStore: Date.now()
};
const getters = {
recentActivity: state => state.recentActivityStore,
recentActivityTiming: state => state.timingStore
};
const actions = {
async fetchRecentActivityData({ commit }) {
const recentAct = this.state.recentactivity.recentActivityStore
if(_.isEmpty(recentAct)) {
const response = await axios.get('/recent/activity')
commit('UPDATE_RECENT_ACTIVITY', response.data)
}
commit('UPDATE_TIMING', Date.now())
}
};
const mutations = {
UPDATE_RECENT_ACTIVITY: (state, data) => {
state.recentActivityStore = data
},
UPDATE_TIMING: (state, data) => {
state.timingStore = data
}
};
export default {
state,
getters,
actions,
mutations
};
How to make my v-for
reload without refresh page manual? Then 3 minutes ago
then 4 minutes ago
happened
Thanks
Upvotes: 0
Views: 471
Reputation: 1956
Codepen : https://codepen.io/anon/pen/qvgxRJ
To solve this create a vue filter
. Code : Vuejs time ago filter
filters: {
timeago: function (pdate, ctime) {
if (!pdate || !ctime) return ''
return moment(pdate).from(ctime)
}
},
apply this filter in HTML
<i>{{act.created_at | timeago(currenttime)}}</i>
It calculates the time ago based on current time. Then in setInterval update the currenttime every 50 seconds. It will update the component every 50 seconds.
data:()=>({
currenttime: Date.now(),
timer: ''
}),
created() {
this.fetchRecentActivityData()
this.timer = setInterval(() => {this.currenttime = Date.now()}, 50000);
}
Final Code.
export default {
data:()=>({
currenttime: Date.now(),
timer: ''
}),
filters: {
timeago: function (pdate, ctime) {
if (!pdate || !ctime) return ''
return moment(pdate).from(ctime)
}
},
created() {
this.fetchRecentActivityData()
this.timer = setInterval(() => {this.currenttime = Date.now()}, 50000);
},
beforeDestroy() {
clearInterval(this.timer)
},
computed: {
...mapGetters(["recentActivity"])
},
methods: {
...mapActions(["fetchRecentActivityData"]),
},
}
in HTML
<li v-for="act in recentActivity" :key="act._id" :id="act._id">
<div class="activity-meta">
<i>{{act.created_at | timeago(currenttime)}}</i>
<span v-html="act.activity"></span>
<h6>by <a href="#" v-html="act.sent_name"></a></h6>
</div>
</li>
Upvotes: 1