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?
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:
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 intodata()
. So if you are usingthis
into yourdata
method you may want to apply the context withObject.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.
Most helpful comment
Caution,
Object.assign(this.$data, this.$options.data())
does not bind the context intodata()
. So if you are usingthis
into yourdata
method you may want to apply the context with