Bertho Joris
Bertho Joris

Reputation: 1601

Best way to re-render v-for when I change my route in vue.js or without reload page manual

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?

If you see enter image description here

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

Answers (1)

dagalti
dagalti

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

Related Questions