Properly adding v-model support to a component (vue.js)

This is one of those things I always forget that’s hard to google properly.

In a child component, adding v-model support starts with a ‘value’ prop. This is the input value arriving at the child component. In the example below, I’m expecting to work with an array.

  props: {
    value: {
      default: () => [],
      type: Array,
    },
  },

We don’t want to mutate the underlying passed in value when it gets changed in the component, so the value prop is cloned into a data property.

  data() {
    return {
      editingRow: false,
      sections: [...this.value]
    }
  },

From here on in, we manipulate only the sections data, never touching the input value prop.

 saveSection(){
      this.sections.push(this.editingRow);
      this.editingRow = false;
}

When it’s time to notify the parent and sync the changes (on clicking save, or just on a practical point within the app), we emit a ‘input’ event with the new contents of the value.

this.$emit('input', this.sections);