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)事件更新绑定的数据

相关推荐
神舟之光21 分钟前
jwt权限控制简单总结(乡村意见簿-vue-express-mongdb)
前端·vue.js·express
流光墨佰1 小时前
我做了一个专为油猴打造的轻量级 Vue 组件注入库
vue.js
踩着两条虫6 小时前
AI驱动的Vue3应用开发平台 深入探究(十三):物料系统之区块与页面模板
前端·vue.js·人工智能·架构·系统架构
luanma1509807 小时前
Laravel 8.X重磅特性全解析
前端·javascript·vue.js·php·lua
tzy2339 小时前
Vue和React之争
前端·vue.js·react.js
网络点点滴9 小时前
Vue3中toRaw和MarkRaw
前端·javascript·vue.js
AI服务老曹10 小时前
掌握核心代码:基于 Spring Boot + Vue 的 AI 视频管理平台源码架构与二次开发实战(全开源/低代码/私有化)
vue.js·人工智能·spring boot
蜡台10 小时前
Vue 组件通信的 12 种解决方案
前端·javascript·vue.js·props
YAY_tyy15 小时前
Vue3 + Three.js 实战:自定义 3D 模型加载与交互全流程
前端·javascript·vue.js·threejs
2301_7806698621 小时前
前端logo替换开发
前端·vue.js