使用自定义组件v-model,界面不更新数据

新手上路,请多包涵

父组件chat.vue

<template>
  <div class="chat">
    <h2>chat-data:{{Data.text}}</h2>
    <List v-model="Data" v-model:text="txt" @update:model-value="inputFunc($event)"/>
    <h2>chat-text:{{txt}}</h2>
  </div>
</template>

<script lang="ts">
import { defineComponent, ref, reactive } from 'vue'

import List from '../list/list.vue'

export default defineComponent({
  name: 'chat',
  components:{
    List
  },
  setup() {
    let txt=ref('')
    let Data=reactive<any>({
      placeholder:'请输入',
      text:''
    })
    const inputFunc=(event:any)=>{
      console.log('inputFunc:',event.text)
      Data.text = event.text
      console.log(Data.text)
    }
    return {
      txt,
      Data,
      inputFunc
    }
  }
})
</script>

<style scoped>
.chat{
  padding: 100px 0;
}
</style>

子组件:list.vue

<template>
  <div class="list" ref="formRef">
    list-modelValue: <input type="text" :value="modelValue.text" :placeholder="modelValue.placeholder"  @input="modelValueChange($event)">
    list-text: <input type="text" :value="text"  @input="modelValueChange1($event)">
  </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue'

export default defineComponent({
  name: 'list',
  props:{
    // 组件的双向绑定的话,v-model冒号后面不写值,默认就是modelValue 进行接收
    modelValue: {
      type: Object,
      required: true
    },
    text:String,
  },
  emits: ['update:modelValue','update:text'],
  setup(props, { emit }) {
    const modelValueChange = (event: any) => {
      console.log('handleValueChange')
      console.log(event.target.value)
      let val = event.target.value
      // 执行这个方法之后,就会传输到父组件,实现双向数据绑定
      emit('update:modelValue',{
        ...props.modelValue,
        text:val
      })
    }
    const modelValueChange1 = (event: any) => {
      console.log('handleValueChange')
      emit('update:text',event.target.value)
    }
    return {
      modelValueChange,
      modelValueChange1
    }
  }
})
</script>

<style scoped></style>

为什么我在父组件可以监听到 Data.text 的更改,但是界面上只更改一次?
但是用ref绑定的数据就没有问题

image.png

阅读 5.1k
1 个回答

双向绑定是双向的,子组件变化同步修改父组织间的值,反之一样,因此你需要在子组件内容通过 watch 监听 modelValue 变化并同步修改子组件内部对应的值。

一个简单的例子:

ParentComp.vue:

<template>
  <ChildComp v-model="value"></ChildComp>
</teamplate>

<script lang="ts">
import { defineComponent, ref } from 'vue'

export default defineComponent({
  setup() {
    return {
      value: ref('')
    }
  }
})
</script>

ChildComp.vue:

<script lang="ts">
// 省略了 <template>
import { defineComponent, ref, watch } from 'vue'

export default defineComponent({
  props: {
    modelValue: {
      type: String,
      default: ''
    }
  },
  emits: ['update:modelValue'],
  setup(props, { emit }) {
    const currentValue = ref(props.modelValue)

    // 父组件的值变化时同步更新子组件内部的值
    watch(
      () => props.modelValue,
      value => {
        currentValue.value = value
      }
    )

    // 子组件的值变化时通过事件通知父组件更新
    function handleChange(value: string) {
      // emit('on-change', value)
      emit('update:modelValue', value)
    }

    return { currentValue, handleChange }
  }
})
</script>
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题