2

The code below for a vuejs component successfully sets the initial state of the data for playerName, time, and errors. Extracting the initial data to a function allows me to easily reset the data back to the initial state.

Great...But... I only want time and error to get reset to the initial state and I want playerName to continue to persist.

Is there a recommended way to accomplish this? I can only seem to find all or nothing approaches or a clunky approach to reset manually that will require me to remember if I change in the future.

Appreciate you looking and any assistance.

function initialState (){
  return {
    playerName: '', 
    time: 0, 
    errors: 0
  }
}

//In my component:
data: function (){
    return initialState();
} 


//Call this method when I want to start over
methods:{
    reset: function (){
        Object.assign(this.$data, initialState());
    }
}

1 Answer 1

3

You can take the initial state and re-merge your keepers with it before re-assigning like so with a super shorthand inline merge:


export default {

  data: () => ({
    playerName: '', 
    time: 0, 
    errors: 0
  })

  methods: {

    reset () {

      const playerName = ...this.playerName; // Use Spread (...) to clone this.playerName so we don't assign a reactive copy that becomes blank again.

      return Object.assign(this.$data, { ...this.$options.data(), playerName })

    }

  }

}

The inline merge { ...this.$options.data(), playerName } is trait of ES6, the playerName injection is the same as writing:


{ ...this.$options.data(), playerName: ...this.playerName }

What is this.$options.data() doing:

{ ...{ playerName: '', time: 0, errors: 0 }, playerName: ...this.playerName }, 

The three dots is called a Spread Syntax, basically it is merging the data object into our new {} empty object then we are overwriting attributes after the injection.

This overall is the equivalent of writing:


Object.assign(this.$data, () => {

  const data = { playerName: '', time: 0, errors: 0 }

  data.playerName = ...this.playerName

  return data

}())
Sign up to request clarification or add additional context in comments.

2 Comments

I have been playing around with variations of this and have learned a bunch; Thanks!. One question - With the inline merge in ES6, can we remove Object.Assign from this all together? i.e. this.$data = { ...this.$options.data(), playerName }? Thanks again.
I remember having a problem not using Object.assign so i always use it; but I can't remember why assigning straight to this.$data was bad, I think it broke reactivity or nested reactivity or something.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.