Vue: Is there a way to reset a component?

Created on 2 Feb 2015  ·  20Comments  ·  Source: vuejs/vue

Currently if there's a component I want to reinitialize, I have to include the component as an expression, set that expression to blank, then reset the expression back to the component

<div v-component="{{currentComponent}}"></div>
container.currentComponent = '';
Vue.nextTick(function () {
  container.currentComponent = 'origional-component';
});

Is there a better way to do this?

Most helpful comment

Caution, Object.assign(this.$data, this.$options.data()) does not bind the context into data(). So if you are using this into your data method you may want to apply the context with

Object.assign(this.$data, this.$options.data.apply(this))

All 20 comments

That's an interesting problem. Since you know that all a component's state is stored in the $data variable, you can always just override it with the original data. And you can store that original data (or rather a function that generates it) in the same module as the component like this:

//This function is exactly the same as your data function for the component originally was
function getDefaultData() {
    return {
        a: "A",
        b: "B"
    }
}

module.exports = {
    data: getDefaultData,
    methods: {
        resetData: function () {
            this.$data = getDefaultData();
        }
    }
};

This is assuming that your components are CommonJS modules, which I recommend doing anyway with Browserify and the Vueify transform.

This seems like it should work, thanks!

@TMiguelT @cheapsteak it doesn't work anymore in Vue 2.0

var defaultData = {
    a: "A",
    b: "B"
}

module.exports = {
data: defaultData ,
methods: {
resetData: function () {
this.$data = defaultData ;
}
}
};

I write it like above, it can't work. it must be a function to get the default data when you wanna reset. why?

You can do the above in Vue 2.0 with Object.assign(this.$data, getDefaultData()). Here's a reference http://codepen.io/CodinCat/pen/ameraP?editors=0010

it works, thx :)

You can do this: Object.assign(this.$data, this.$options.data())

Object.assign(this.$data, this.$options.data()) it works

Caution, Object.assign(this.$data, this.$options.data()) does not bind the context into data(). So if you are using this into your data method you may want to apply the context with

Object.assign(this.$data, this.$options.data.apply(this))

@thollar13 : thank you for the solution. How would that work in a component where data is a function?

@wsw70 Object.assign(this.$data, this.$options.data()) works with components.

What about resetting to initial property values? And, running all lifecycle hooks?

Object.assign(this.$data, this.$options.data()) doesn't work for me. Objects aren't being reset:

const dataDefaults = {
    _object: {
        a: false,
        b: ''
    },
};

```js
data() {
return {
_object: dataDefaults._object,
}
},

```js
reset() {
    Object.assign(this.$data, this.$options.data())
}

@bradley-varol Because you're initially setting $data._object to dataDefaults._object via reference, then when you make changes to those properties and call reset(), it will only set _object back to the same object reference. Take a look at the Object.assign documentation.

For anyone stumbling upon this via Google, I'd warn against using this.$options.data. It does not play nicely with mixins that add default data properties. Specifically I encountered bad behavior from vue-async-computed where my properties didn't seem to update after calling this.

Best way, changing component key: http://michaelnthiessen.com/force-re-render/

As of February 2019, there's excellent package that handles default data and resetting components using a mixin with ease:

https://github.com/ianwalter/vue-component-reset#readme

You can do the above in Vue 2.0 with Object.assign(this.$data, getDefaultData()). Here's a reference http://codepen.io/CodinCat/pen/ameraP?editors=0010

This works for the data parent, but doesn't update the data passed to the child component.

Best way, changing component key: http://michaelnthiessen.com/force-re-render/

Adding the key to the component did the trick for me.

Caution, Object.assign(this.$data, this.$options.data()) does not bind the context into data(). So if you are using this into your data method you may want to apply the context with

Object.assign(this.$data, this.$options.data.apply(this))

This is a very good point to keep in mind while resetting like this because I use variables in data as key:value mapping for function calls for various scenarios:

      // Handlers are method definitions which I call dynamically on run-time
      optionModifierHandlers: {
        'option1': this.option1Handler,
        'option2': this.option2Handler,
        'option3': this.option3Handler,
      }

When you have variables like this, these do not reset automatically on just
this.$options.data()

Doing this always gave me 'undefined' values.

So, make sure you apply the context as mentioned by @Ifnot , This will once again bind the component's methods to the data variables.

Was this page helpful?
0 / 5 - 0 ratings