How to re-mount a component in VueJS?

28,083

Solution 1

The trick is to alter the key

When the key changes, vue regards it as a new component, so it will unmount the "old" component, and mount a "new" component.

See example, the created() hook will only run once, so if you see the value change, you're seeing a brand new object.

example:

Vue.component('my-component', {
  template: `<div>{{ rand }}</div>`,
  data() {
    return {
      rand: ''
    }
  },
  created() {
    this.rand = Math.round(Math.random() * 1000)
  }
});

new Vue({
  el: '#app',
  data: {
    componentKey:0
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.8/vue.min.js"></script>

<div id="app">
  <my-component :key="componentKey"></my-component>
  <button @click="componentKey=!componentKey">press this button to reload the component</button>
</div>

Solution 2

In your template you'll add the v-if directive:

<template>
  <my-component v-if="renderComponent" />
</template>

In your script you'll add in this method that uses nextTick:

<script>
  export default {
    data() {
      return {
        renderComponent: true,
      };
    },
    methods: {
      forceRerender() {
        // Remove my-component from the DOM
        this.renderComponent = false;

        this.$nextTick(() => {
          // Add the component back in
          this.renderComponent = true;
        });
      }
    }
  };
</script>

This is what's going on here:

Initially renderComponent is set to true, so my-component is rendered When we call forceRerender we immediately set renderComponent to false We stop rendering my-component because the v-if directive now evaluates to false On the next tick renderComponent is set back to true Now the v-if directive evaluates to true, so we start rendering my-component again

Share:
28,083
WoJ
Author by

WoJ

Updated on November 19, 2021

Comments

  • WoJ
    WoJ over 2 years

    I have a component which is mounted as part of the DOM rendering. The skeleton of the application is

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="UTF-8">
        <title>title</title>
      </head>
      <body>
        <div id="app">
          <my-component></my-component>
          <button>press this button to reload the component</button>
        </div>
      </body>
    </html>
    

    <my-component> is functional (it displays a few form inputs) and $emit data to the parent.

    Is there a way to re-mount it? The goal is to have a component content and setup as if it was just rendered for the first time (including a reset of the data() elements which hold its state).

    There are some solutions to that but they all assume a rewrite of data(), which I would like to avoid.

    My understanding is that a component is actuall HTML/CSS/JS code injected in the dom in the right place during the rendering so I fear that the concept of "re-mounting" it does not exist - I just wanted to make sure before going the data()-rewrite way.