Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is there a way to reset a component? #702

Closed
cheapsteak opened this issue Feb 2, 2015 · 21 comments
Closed

Is there a way to reset a component? #702

cheapsteak opened this issue Feb 2, 2015 · 21 comments

Comments

@cheapsteak
Copy link
Contributor

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?

@multimeric
Copy link

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.

@cheapsteak
Copy link
Contributor Author

This seems like it should work, thanks!

@Kaijun
Copy link

Kaijun commented Oct 21, 2016

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

@skywalker2013
Copy link

skywalker2013 commented Oct 24, 2016

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?

@thollar13
Copy link

thollar13 commented Nov 4, 2016

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

@dszmaj
Copy link

dszmaj commented Nov 13, 2016

it works, thx :)

@shammadahmed
Copy link

shammadahmed commented Feb 20, 2017

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

@frank0718
Copy link

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

@IfnotFr
Copy link

IfnotFr commented Jun 16, 2017

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))

@wsw70
Copy link

wsw70 commented Aug 7, 2017

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

@shammadahmed
Copy link

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

@ferndot
Copy link

ferndot commented Sep 4, 2018

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

@bradley-varol
Copy link

bradley-varol commented Dec 19, 2018

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

const dataDefaults = {
    _object: {
        a: false,
        b: ''
    },
};
data() {
     return {
          _object: dataDefaults._object,
    }
},
reset() {
    Object.assign(this.$data, this.$options.data())
}

@Cobertos
Copy link

@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.

@Cobertos
Copy link

Cobertos commented Dec 19, 2018

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.

@guarah
Copy link

guarah commented Dec 20, 2018

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

@bradley-varol
Copy link

bradley-varol commented Mar 14, 2019

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

@aislanmaia
Copy link

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.

@khandelwal-arpit
Copy link

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

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

@dhwanils95
Copy link

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.

@TokugawaTakeshi
Copy link

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

Is this solution actual for Vue 3.X?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests