[javascript] Can you force Vue.js to reload/re-render?

Just a quick question.

Can you force Vue.js to reload/recalculate everything? If so, how?

This question is related to javascript vue.js

The answer is


Try to use this.$router.go(0); to manually reload the current page.


just add this code:

this.$forceUpdate()

GoodLuck


Worked for me

    data () {
        return {
            userInfo: null,
            offers: null
        }
    },

    watch: {
        '$route'() {
            this.userInfo = null
            this.offers = null
            this.loadUserInfo()
            this.getUserOffers()
        }
    }

So there's two way you can do this,

1). You can use $forceUpdate() inside your method handler i.e

<your-component @click="reRender()"></your-component>

<script>
export default {
   methods: {
     reRender(){
        this.$forceUpdate()
     }
   }
}
</script>

2). You can give a :key attribute to your component and increament when want to rerender

<your-component :key="index" @click="reRender()"></your-component>

<script>
export default {
   data() {
     return {
        index: 1
     }
   },
   methods: {
     reRender(){
        this.index++
     }
   }
}
</script>

I found a way. It's a bit hacky but works.

vm.$set("x",0);
vm.$delete("x");

Where vm is your view-model object, and x is a non-existent variable.

Vue.js will complain about this in the console log but it does trigger a refresh for all data. Tested with version 1.0.26.


Sure .. you can simply use the key attribute to force re-render (recreation) at any time.

<mycomponent :key="somevalueunderyourcontrol"></mycomponent>

See https://jsfiddle.net/mgoetzke/epqy1xgf/ for an example

It was also discussed here: https://github.com/vuejs/Discussion/issues/356#issuecomment-336060875


I had this issue with an image gallery that I wanted to rerender due to changes made on a different tab. So tab1 = imageGallery, tab2 = favoriteImages

tab @change="updateGallery()" -> this forces my v-for directive to process the filteredImages function every time I switch tabs.

<script>
export default {
  data() {
    return {
      currentTab: 0,
      tab: null,
      colorFilter: "",
      colors: ["None", "Beige", "Black"], 
      items: ["Image Gallery", "Favorite Images"]
    };
  },
  methods: {
    filteredImages: function() {
      return this.$store.getters.getImageDatabase.filter(img => {
        if (img.color.match(this.colorFilter)) return true;
      });
    },
    updateGallery: async function() {
      // instance is responsive to changes
      // change is made and forces filteredImages to do its thing
      // async await forces the browser to slow down and allows changes to take effect
      await this.$nextTick(function() {
        this.colorFilter = "Black";
      });

      await this.$nextTick(function() {
        // Doesnt hurt to zero out filters on change
        this.colorFilter = "";
      });
    }
  }
};
</script>

sorry guys, except page reload method(flickering), none of them works for me (:key didn't worked).

and i found this method from old vue.js forum which is works for me:

https://github.com/vuejs/Discussion/issues/356

<template>
    <div v-if="show">
       <button @click="rerender">re-render</button>
    </div>
</template>
<script>
    export default {
        data(){
            return {show:true}
        },
        methods:{
            rerender(){
                this.show = false
                this.$nextTick(() => {
                    this.show = true
                    console.log('re-render start')
                    this.$nextTick(() => {
                        console.log('re-render end')
                    })
                })
            }
        }
    }
</script>

using v-if directive

<div v-if="trulyvalue">
    <component-here />
 </div>

So simply by changing the value of trulyvalue from false to true will cause the component between the div to rerender again


This has worked for me.

created() {
            EventBus.$on('refresh-stores-list', () => {
                this.$forceUpdate();
            });
        },

The other component fires the refresh-stores-list event will cause the current component to rerender


<my-component :key="uniqueKey" />

along with it use this.$set(obj,'obj_key',value) and update uniqueKey for every update in object (obj) value for every update this.uniqueKey++

it worked for me this way


Why?

...do you need to force an update?

Perhaps you are not exploring Vue at its best:

To have Vue automatically react to value changes, the objects must be initially declared in data. Or, if not, they must be added using Vue.set().

See comments in the demo below. Or open the same demo in a JSFiddle here.

_x000D_
_x000D_
new Vue({_x000D_
  el: '#app',_x000D_
  data: {_x000D_
    person: {_x000D_
      name: 'Edson'_x000D_
    }_x000D_
  },_x000D_
  methods: {_x000D_
    changeName() {_x000D_
      // because name is declared in data, whenever it_x000D_
      // changes, Vue automatically updates_x000D_
      this.person.name = 'Arantes';_x000D_
    },_x000D_
    changeNickname() {_x000D_
      // because nickname is NOT declared in data, when it_x000D_
      // changes, Vue will NOT automatically update_x000D_
      this.person.nickname = 'Pele';_x000D_
      // although if anything else updates, this change will be seen_x000D_
    },_x000D_
    changeNicknameProperly() {_x000D_
      // when some property is NOT INITIALLY declared in data, the correct way_x000D_
      // to add it is using Vue.set or this.$set_x000D_
      Vue.set(this.person, 'address', '123th avenue.');_x000D_
      _x000D_
      // subsequent changes can be done directly now and it will auto update_x000D_
      this.person.address = '345th avenue.';_x000D_
    }_x000D_
  }_x000D_
})
_x000D_
/* CSS just for the demo, it is not necessary at all! */_x000D_
span:nth-of-type(1),button:nth-of-type(1) { color: blue; }_x000D_
span:nth-of-type(2),button:nth-of-type(2) { color: red; }_x000D_
span:nth-of-type(3),button:nth-of-type(3) { color: green; }_x000D_
span { font-family: monospace }
_x000D_
<script src="https://unpkg.com/vue"></script>_x000D_
_x000D_
<div id="app">_x000D_
  <span>person.name: {{ person.name }}</span><br>_x000D_
  <span>person.nickname: {{ person.nickname }}</span><br>_x000D_
  <span>person.address: {{ person.address }}</span><br>_x000D_
  <br>_x000D_
  <button @click="changeName">this.person.name = 'Arantes'; (will auto update because `name` was in `data`)</button><br>_x000D_
  <button @click="changeNickname">this.person.nickname = 'Pele'; (will NOT auto update because `nickname` was not in `data`)</button><br>_x000D_
  <button @click="changeNicknameProperly">Vue.set(this.person, 'address', '99th st.'); (WILL auto update even though `address` was not in `data`)</button>_x000D_
  <br>_x000D_
  <br>_x000D_
  For more info, read the comments in the code. Or check the docs on <b>Reactivity</b> (link below)._x000D_
</div>
_x000D_
_x000D_
_x000D_

To master this part of Vue, check the Official Docs on Reactivity - Change Detection Caveats. It is a must read!


This seems like a pretty clean solution from matthiasg on this issue:

you can also use :key="someVariableUnderYourControl" and change the key when you want to component to be completely rebuilt

For my use case, I was feeding a Vuex getter into a component as a prop. Somehow Vuex would fetch the data but the reactivity wouldn't reliably kick in to rerender the component. In my case, setting the component key to some attribute on the prop guaranteed a refresh when the getters (and the attribute) finally resolved.


Use vm.$set('varName', value). Look for details into Change_Detection_Caveats.


<router-view :key="$route.params.slug" />

just use key with your any params its auto reload children..


Please read this http://michaelnthiessen.com/force-re-render/

The horrible way: reloading the entire page
The terrible way: using the v-if hack
The better way: using Vue’s built-in forceUpdate method
The best way: key-changing on your component

<template>
   <component-to-re-render :key="componentKey" />
</template>

<script>
 export default {
  data() {
    return {
      componentKey: 0,
    };
  },
  methods: {
    forceRerender() {
      this.componentKey += 1;  
    }
  }
 }
</script>

I also use watch: in some situations.


The approach of adding :key to the vue-router lib's router-view component cause's fickers for me, so I went vue-router's 'in-component guard' to intercept updates and refresh the entire page accordingly when there's an update of the path on the same route (as $router.go, $router.push, $router.replace weren't any help). The only caveat with this is that we're for a second breaking the singe-page app behavior, by refreshing the page.

  beforeRouteUpdate(to, from, next) {
    if (to.path !== from.path) {
      window.location = to.path;
    }
  },

In order to reload/re-render/refresh component, stop the long codings. There is a Vue.JS way of doing that.

Just use :key attribute.

For example:

<my-component :key="unique" />

I am using that one in BS Vue Table Slot. Telling that I will do something for this component so make it unique.