vue3中自定义组件的双向绑定

我们有时候需要抽离一些模块,这些模块中可能包含input,而我们的子模块数据又来源于父组件中。这时候如何双向同步就成了不得不面对的问题。我们通过一个简单的实例来看看。

第一种解法就是父组件传值,子组件通过:value="num" @input="updateNum",然后每次子组件里input的值发生改变的时候 emit('update:num', event.target.value)事件。

复制代码
 <div class="wrap">
            <div class="list_item" v-for="(item,index) of skuData.list">
              {{item.id}}
              <Ipt v-model:num="item.num"  />
          </div>
     </div>
 <button @click="test">查看数据</button>


const skuData=ref({
  list:[
    {id:"0001",num:1},
    {id:"0002",num:2},
    {id:"0003",num:3},
    {id:"0004",num:4},
  ]
})
----------------------------------------------
子组件
 <template>
   <div>
    <p>input数据</p>
    <input type="text" :value="num" @input="updateNum" />
   </div>
 </template>

const emit=defineEmits(['update:num'])
const props=defineProps({
   modelValue: {
         type: Object,
         required: true
    },
    num: {
      type: Number,
      default: 0
    }       
})
 
const  updateNum=(event) =>{
  emit('update:num', event.target.value)
}

第二种解法其实同理,只不过父子组件中双向同步的不是一个具体的num值而是一个对象。

复制代码
 <div class="wrap">
            <div class="list_item" v-for="(item,index) of skuData.list">
              {{item.id}}
              <Ipt v-model="skuData.list[index]"  />
          </div>
     </div>
  <button @click="test">查看数据</button>

const skuData=ref({
  list:[
    {id:"0001",num:1},
    {id:"0002",num:2},
    {id:"0003",num:3},
    {id:"0004",num:4},
  ]
})

---------------------------------------------------
子组件

template>
  <div>
    <p>input数据</p>
    <input type="text" v-model="localValue.num"/>
  </div>
</template>

<script setup lang="ts">
import { defineProps, defineEmits, watch } from 'vue'

const props = defineProps({
  modelValue: {
    type: Object,
    required: true
  }
})

const emit = defineEmits(['update:modelValue'])

const localValue = props.modelValue  // 直接使用 props.modelValue

watch(
  () => props.modelValue, 
  (newVal) => {
    localValue.num = newVal.num  // 确保直接更新 localValue
  },
  { deep: true, immediate: true }
)

watch(localValue, (newValue) => {
  emit('update:modelValue', newValue)  // 向父组件发出更新
})

这时候当我们更改子组件中input的值的时候父组件的值也会同步更改。不过有一点要注意。

const localValue = props.modelValue 这里不要用const localValue =ref( props.modelValue)同时,更改子组件里input的值以后,父组件的数据格式变成了{id:"0001",num:3,value:{d:"0001",num:3,}},

这里3是更改以后的值。多了一个value。这是vue3自动响应式处理的结果。

推荐使用方式一

相关推荐
LinXunFeng2 小时前
Obsidian - 使用 Share Note 分享笔记并自部署
前端·笔记·github
乘风gg6 小时前
为什么AI 时代来临,大部分人吃不到红利
前端·ai编程·claude
恋猫de小郭6 小时前
Android 限制侧载新进展,谷歌联合国内厂商推验证计划
android·前端·flutter
IT_陈寒6 小时前
Redis内存爆了,原来我漏掉了这个致命配置
前端·人工智能·后端
恋猫de小郭6 小时前
解读 Android 17 全新内存限制,有没有“豁免”后门?
android·前端·flutter
Hyyy7 小时前
理解LLM的基本工作原理:预训练、微调、推理的区别
前端
Gatlin8 小时前
前端逆向与反逆向:一场猫鼠游戏的底层逻辑与实战
前端
代码煮茶8 小时前
React 组件封装方法论 —— 以 Todo App 为例
javascript·react.js
Pedantic8 小时前
本地通知(Local Notifications)学习笔记
前端
任沫8 小时前
Agent之Function Call
javascript·人工智能·go