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

相关推荐
java_heartLake1 小时前
Vue3之性能优化
javascript·vue.js·性能优化
ddd君317742 小时前
组件的声明、创建、渲染
vue.js
前端没钱2 小时前
从 Vue 迈向 React:平滑过渡与关键注意点全解析
前端·vue.js·react.js
顽疲3 小时前
springboot vue 会员收银系统 含源码 开发流程
vue.js·spring boot·后端
羊小猪~~3 小时前
前端入门之VUE--ajax、vuex、router,最后的前端总结
前端·javascript·css·vue.js·vscode·ajax·html5
摸鱼了3 小时前
🚀 从零开始搭建 Vue 3+Vite+TypeScript+Pinia+Vue Router+SCSS+StyleLint+CommitLint+...项目
前端·vue.js
2401_857600954 小时前
基于 SSM 框架 Vue 电脑测评系统:赋能电脑品质鉴定
前端·javascript·vue.js
天之涯上上4 小时前
Pinia 是一个专为 Vue.js 3 设计的状态管理库
前端·javascript·vue.js
CodeChampion6 小时前
60.基于SSM的个人网站的设计与实现(项目 + 论文)
java·vue.js·mysql·spring·elementui·node.js·mybatis
Elena_Lucky_baby6 小时前
实现路由懒加载的方式有哪些?
前端·javascript·vue.js