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

相关推荐
你别说话了1 天前
Vue项目解决跨域
前端·javascript·vue.js
学习星球1 天前
Solid.js 实战:拆解官方 RealWorld 项目
开发语言·javascript·vue.js
尚可签2 天前
基于 Spring Boot + Vue 的 AI 智能在线订餐系统
vue.js·人工智能·spring boot
MacroZheng2 天前
腾讯又开源了一个新项目,用起来真优雅!
前端·vue.js·人工智能
张人玉2 天前
基于 Vue 3 + ECharts + Three.js + Express + SQLite——智慧城市数字孪生可视化平台
javascript·vue.js·信息可视化·sqlite·echarts
山川志~2 天前
Vue + Element UI 实战:如何实现表格时间、金额字段排序
vue.js·ui·elementui
_codemonster2 天前
Vue中的ref和reactive到底在干嘛
前端·javascript·vue.js
前端fighter2 天前
线上崩溃?使用 TRAE Work 5分钟把混淆日志翻译成人话并输出复盘报告
前端·vue.js·程序员
常宇佳2 天前
vue3 实战系列之无法识别vue组件
前端·javascript·vue.js
你别说话了2 天前
动态给vue的Data添加一个新的属性数据更新但是页面没有更新,怎么解决
前端·javascript·vue.js