javascriptvue.jstwo-way-binding

Two-way binding in Vue.js with prop.sync and watcher


I'm having trouble understanding the two-way binding between a parent and child component. So far, what I've read seems to recommend using prop.sync in conjunction with watching the prop. E.g:

Parent:

<child-component :childProp.sync="parentData"></child-component>

Child:

<template>
  <input v-model="childData" @input="$emit('update:childProp', childData);"></input>
</template>
<script>
  export default {
    props: ['childProp'],
    data() {
      childData: childProp
    },
    watch: {
      childProp(newValue) {
        this.childData = newValue;
      }
    }
  }
</script>

My problem with this is, wouldn't this create some sort of redundancy when either the parentData or the childData is updated? The flow would be thus (for parentData changed):

  1. parentData changes ->
  2. triggers watch ->
  3. childData changes ->
  4. triggers .sync ->
  5. parentData updated.

I'm assuming the cycle stops at step #5 because the updated value of the parentData is the same as the old value, so parentData doesn't really change, hence step #2 watcher is not triggered.

My problem with this is, if my reasoning is right, there will be some sort of redundancy in that changes to the parentData will go to the child and reflect back to itself, and vice versa. The reflection is the redundancy. Am I right so far? Or is my understanding of this completely off?

If I'm wrong, please help me understand where I went wrong. But if I'm right, then is there another way to achieve two-way binding without this redundancy?


Solution

  • I suppose you can simplify a child component code like this:

    <template>
      <input :value="childProp" @input="$emit('update:childProp', $event);"></input>
    </template>
    <script>
      export default {
        props: ['childProp']
      }
    </script>