Vue 3 -子组件的双向数据绑定问题

j91ykkif  于 2022-11-25  发布在  Vue.js
关注(0)|答案(2)|浏览(386)

在Vue 3中,我在父组件和其子组件(表单)之间的双向数据绑定上遇到了麻烦。

父版本

<template>
  <h5>{{ record.title }}</h5>
  <ChildForm v-model:record="record"></ChildForm>
</template>

<script lang="ts">
export default {
  data() {
    record: undefined
  },
  created() {
    //code to fetch record
    this.$data.record = new Record(responseJson);
  },
  watch: {
    record: function(newRecord, oldRecord) {
      alert("change detected!");
      //perform appropriate logic when record is changed in child
    }
  }
}
</script>

子版本

<template>
  <InputText v-model="record.title"></InputText>
  <InputText v-model="record.description"></InputText>
</template>

<script lang="ts">
export default {
  props: {
    record: {
      type: Object as () => RecordModel
    }
  },
  emits: ["update:record"]
}

如果我在ChildForm的title输入框中更改了title,父表单将准确地反映h5头中的更改。但是,watch函数永远不会被触发。
我必须做什么才能在子对象更改模型对象的值时触发父对象的watch方法?

eimct9ow

eimct9ow1#

几个注意事项:
1.你直接修改了prop,这是不受欢迎的,而且从技术上讲从来没有发射update:record,所以v模型本质上是无用的。如果你发射了,那么手表就会像你预期的那样发射。如果你想知道如何做的例子,请参见this answer,它显示了vue2的jist,你只需要修改它来使用新的update:prop事件名称。
1.如果你想继续直接修改道具,那么你根本不需要v-model:record,只需要使用:record="record",并让观察者变深

watch: {
    record: {
        handler(newRecord, oldRecord) {
            alert("change detected!");
        },
        deep: true
    }
}
pw9qyyiw

pw9qyyiw2#

Steven B链接到的答案是正确的,但它需要一些工作来适应Vue 3和我的情况:

父版本

<template>
  <h5>{{ record.title }}</h5>
  <ChildForm v-model:record="record" v-on:update:record="parentRecordUpdate"></ChildForm>
</template>

<script lang="ts">
export default {
  data() {
    record?: undefined
  },
  created() {
    //code to fetch record
    this.$data.record = new Record(responseJson);
  },
  methods: {
    parentRecordUpdate() {
      alert("change detected!");
      //perform appropriate logic when record is changed in child
    }
  }
}
</script>

子版本

<template>
  <InputText v-bind:value="record.title" @input="childUpdateRecord('title', $event.target.value)"></InputText>
  <InputText v-bind:value="record.status" @input="childUpdateRecord('status', $event.target.value)"></InputText>
</template>

<script lang="ts">
export default {
  props: {
    record: {
      type: Object as () => RecordModel
    }
  },
  emits: ["update:record"],
  methods: {
    childUpdateRecord(field: string, value: string) {
      //Update with whatever happened in the InputText box
      this.$props.record.setAttribute(field, value);
      //calling $emit triggers the parent's update method
      this.$emit('update:record', this.$props.record);
    }
  }
}

相关问题