Vue中父组件通过v-model向子组件传对象参数

描述: Vue中父组件通过v-model向子组件传递一个对象,在子组件实现一个能够对object key-value进行编辑的组件封装。

父组件文件

js 复制代码
 <form-child v-model="configMap"></form-child>
 
import formChild from '@/components/formchild.vue'
import { defineComponent, ref} from 'vue'

export default defineComponent({
    name: 'form',
    components: {
        formChild
    },
    setup() {
        const configMap = ref({
            name: 'summer',
            age: '18'       
        })
       

        return {
            configMap,
        }
    }
})

子组件 formchild.vue

html 复制代码
<template>
  <div>
    <div v-for="(item, index) in configEntries" :key="index" class="row">
       <a-row class="item">
        <a-col :span="8">
          <a-input type="text" v-model:value="item.key" @change="updateConfigMap"></a-input>
        </a-col>
        <a-col :span="8" :offset="1">
          <a-input type="text" v-model:value="item.value" @change="updateConfigMap"></a-input>
        </a-col>
        <a-col :offset="1">
          <close-circle-outlined @click="() => deleteByIndex(index)" :style="{fontSize: '16px', color: '#08c', marginTop: '7px'}"/>
        </a-col>
      </a-row> 
    </div>
    <a-button type="primary" @click="addConfig">
      add
    </a-button>

  </div>
</template>
js 复制代码
import { defineComponent, toRef } from "vue";
import { CloseCircleOutlined } from '@ant-design/icons-vue';

export default defineComponent({
  name: 'formchild',
  components: {
    CloseCircleOutlined
  },
  props: {
    modelValue: Object
  },
  emits: ['update:modelValue'],
  setup(props, { emit }) {
   
   // 第一步 将父组件传递过来的对象转变为一个数组
    const configData = toRef({...props.modelValue});
    const configEntries = objToArray(configData.value);

    // 第二步 对每一个key、value可以编辑进行处理
    const updateConfigMap = () => {
      configData.value = arrayToObj(configEntries)
      emit('update:modelValue', configData.value)
    }
    // 第三步 添加/删除事件的处理
    const addConfig = () => {  
      configEntries.push({
        key: '',
        value: ''
      })
      updateConfigMap()
    }

    const deleteByIndex = (index)=> {
        configEntries.splice(index, 1)
        updateConfigMap()
    }
    
	const arrayToObj = (arr: any[]) => {
	    return arr.reduce((obj, item) => {
	        obj[item.key] = item.value;
	        return obj;
	     }, {})
	}

	const objToArray = (arr: any) => {
	    return Object.entries(arr).map(([key, value]) =>(
	        {
	         key,
	         value
	       }
	    ))
	}

    return {
      configEntries,
      addConfig,
      updateConfigMap,
      deleteByIndex,
    }
  }
})

父组件通过v-model传递,子组件通过props:{modelValue: Object}进行接收,通过 emit('update:modelValue', configData.value)事件更新绑定的数据

相关推荐
醉酒的李白、5 分钟前
Vue3 组件通信本质:Props 下发,Emits 回传
前端·javascript·vue.js
小眼哥24 分钟前
SpringBoot整合Vue代码生成exe运行程序以及windows安装包
vue.js·windows·spring boot
徐小夕1 小时前
PDF无限制预览!Jit-Viewer V1.5.0开源文档预览神器正式发布
前端·vue.js·github
吴声子夜歌1 小时前
Vue.js——自定义指令
前端·vue.js·flutter
小芝麻咿呀1 小时前
vue--面试题第一部分
前端·javascript·vue.js
早起傻一天~G2 小时前
vue2+element-UI表格封装
javascript·vue.js·ui
Ruihong6 小时前
Vue v-bind 转 React:VuReact 怎么处理?
vue.js·react.js·面试
前端那点事8 小时前
Vue插槽用法全解析(Vue2+Vue3适配)| 组件复用必备
vue.js
Ruihong8 小时前
Vue v-on 在 React 中 VuReact 会如何实现?
vue.js·react.js·面试
|晴 天|8 小时前
实现草稿自动保存功能:5秒无操作自动保存
前端·vue.js·typescript