Is there a proper way of resetting a component's initial data in vuejs?
Solution 1
- extract the initial data into a function outside of the component
- use that function to set the initial data in the component
- re-use that function to reset the state when needed.
// outside of the component:
function initialState (){
return {
modalBodyDisplay: 'getUserInput',
submitButtonText: 'Lookup',
addressToConfirm: null,
bestViewedByTheseBounds: null,
location:{
name: null,
address: null,
position: null
}
}
}
//inside of the component:
data: function (){
return initialState();
}
methods:{
resetWindow: function (){
Object.assign(this.$data, initialState());
}
}
Solution 2
Caution,
Object.assign(this.$data, this.$options.data())
does not bind the context into data().
So use this:
Object.assign(this.$data, this.$options.data.apply(this))
cc this answer was originally here
Solution 3
To reset component data
in a current component instance you can try this:
Object.assign(this.$data, this.$options.data())
Privately I have abstract modal component which utilizes slots to fill various parts of the dialog. When customized modal wraps that abstract modal the data referred in slots belongs to parent component scope. Here is option of the abstract modal which resets data every time the customized modal is shown (ES2015 code):
watch: {
show (value) { // this is prop's watch
if(value) {
Object.assign(this.$parent.$data, this.$parent.$options.data())
}
}
}
You can fine tune your modal implementation of course - above may be also executed in some cancel
hook.
Bear in mind that mutation of $parent
options from child is not recommended, however I think it may be justified if parent component is just customizing the abstract modal and nothing more.
Solution 4
If you are annoyed by the warnings, this is a different method:
const initialData = () => ({})
export default {
data() {
return initialData();
},
methods: {
resetData(){
const data = initialData()
Object.keys(data).forEach(k => this[k] = data[k])
}
}
}
No need to mess with $data.
Solution 5
I had to reset the data to original state inside of a child component, this is what worked for me:
Parent component, calling child component's method:
<button @click="$refs.childComponent.clearAllData()">Clear All</button >
<child-component ref='childComponent></child-component>
Child component:
- defining data in an outside function,
- referencing data object by the defined function
- defining the clearallData() method that is to be called upon by the parent component
function initialState() {
return {
someDataParameters : '',
someMoreDataParameters: ''
}
}
export default {
data() {
return initialState();
},
methods: {
clearAllData() {
Object.assign(this.$data, initialState());
},
Chris Schmitz
Application engineer at Label Insight, web dev, and maker.
Updated on July 26, 2022Comments
-
Chris Schmitz almost 2 years
I have a component with a specific set of starting data:
data: function (){ return { modalBodyDisplay: 'getUserInput', // possible values: 'getUserInput', 'confirmGeocodedValue' submitButtonText: 'Lookup', // possible values 'Lookup', 'Yes' addressToConfirm: null, bestViewedByTheseBounds: null, location:{ name: null, address: null, position: null } }
This is data for a modal window, so when it shows I want it to start with this data. If the user cancels from the window I want to reset all of the data to this.
I know I can create a method to reset the data and just manually set all of the data properties back to their original:
reset: function (){ this.modalBodyDisplay = 'getUserInput'; this.submitButtonText = 'Lookup'; this.addressToConfirm = null; this.bestViewedByTheseBounds = null; this.location = { name: null, address: null, position: null }; }
But this seems really sloppy. It means that if I ever make a change to the component's data properties I'll need to make sure I remember to update the reset method's structure. That's not absolutely horrible since it's a small modular component, but it makes the optimization portion of my brain scream.
The solution that I thought would work would be to grab the initial data properties in a
ready
method and then use that saved data to reset the components:data: function (){ return { modalBodyDisplay: 'getUserInput', submitButtonText: 'Lookup', addressToConfirm: null, bestViewedByTheseBounds: null, location:{ name: null, address: null, position: null }, // new property for holding the initial component configuration initialDataConfiguration: null } }, ready: function (){ // grabbing this here so that we can reset the data when we close the window. this.initialDataConfiguration = this.$data; }, methods:{ resetWindow: function (){ // set the data for the component back to the original configuration this.$data = this.initialDataConfiguration; } }
But the
initialDataConfiguration
object is changing along with the data (which makes sense because in the read method ourinitialDataConfiguration
is getting the scope of the data function.Is there a way of grabbing the initial configuration data without inheriting the scope?
Am I overthinking this and there's a better/easier way of doing this?
Is hardcoding the initial data the only option?
-
Chris Schmitz about 8 yearsThat did it. Thanks! I did a small edit to the answer, but only because a vue component requires a function returned for data instead of just an object. Your answers concept definitely works and is correct, the edit is just to account for how vuejs handles components.
-
Linus Borg about 8 yearsYou are right about the function for the data property, that was me being sloppy. Thanks for the edit.
-
Sankalp Singha over 7 yearsIt now gives an error :
[Vue warn]: Avoid replacing instance root $data. Use nested data properties instead.
-
CodinCat over 7 years@SankalpSingha Vue 2.0 doesn't allow you to do that anymore. You can use
Object.assign
instead. Here is the working code: codepen.io/CodinCat/pen/ameraP?editors=1010 -
Kivi Shapiro about 7 yearsThis technique now gives a VueJS warning; see stackoverflow.com/questions/40340561/…
-
Ifnot almost 7 yearsCaution, this does not bind the context into
data
. So if you are usingthis
into yourdata
method you can apply the context with :Object.assign(this.$data, this.$options.data.apply(this))
-
Stanislav Ostapenko almost 6 yearsFor this issue - [Vue warn]: Avoid replacing instance root $data. Use nested data properties instead, try this.$data.propName = "new value";
-
Carlos over 4 yearsWhat is the advantage of these way versus location.reload()?
-
lbris about 4 yearsIt is not mandatory to extract the function that sets initial data though. I personally put this function in my component
methods
and then just call it withthis.<my_method_name>
-
Alexander Kim over 3 yearsas of vue 2, use @srmico answer below.
-
Kay Angevare almost 3 yearsPlug and play answer, worked like a charm.
-
Alex Wohlbruck almost 3 yearsIs there a typescript-safe version of this?
-
Eugene Karataev over 2 years@Carlos
location.reload
fully reloads a webpage, which is not what we usually need when trying to reset an individual's component state. -
geoidesic about 2 years@CodinCat that gives error: [Vue warn]: The "data" option should be a function that returns a per-instance value in component definitions. And doesn't work.