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

相关推荐
花菜会噎住2 小时前
Vue3核心语法进阶(computed与监听)
前端·javascript·vue.js
I'mxx2 小时前
【vue(2)插槽】
javascript·vue.js
花菜会噎住2 小时前
Vue3核心语法基础
前端·javascript·vue.js·前端框架
练习前端两年半4 小时前
Vue3 源码深度剖析:有状态组件的渲染机制与生命周期实现
前端·vue.js
533_7 小时前
[vue3 echarts] echarts 动态数据更新 setInterval
vue.js·echarts
jstart千语7 小时前
【vue】创建响应式数据ref和reactive的区别
前端·javascript·vue.js
盗德8 小时前
Vue渲染引擎的范式革命:从虚拟DOM到Vapor模式
前端·vue.js
Dolphin_海豚9 小时前
vapor 的 IR 是如何被 generate 到 render 函数的
前端·vue.js·vapor
初遇你时动了情10 小时前
JS中defineProperty/Proxy 数据劫持 vue3/vue2双向绑定实现原理,react 实现原理
javascript·vue.js·react.js