在日常开发中,会遇到子组件需要修改父组件传过来的参数,vue中是不允许直接进行修改的,原理:为了避免当一个子组件被多个父组件引用时,无法定位数据修改的源头,所以父子组件的参数流向是单向的,但是我们可以通过其他的一些方式,实现子组件修改父组件传来的参数,下面众多方式中的一种:
利用props和emits进行父子组件通信的方式
父组件
- 通过v-bind(语法糖
:)将父组件的参数传递给子组件 - 通过v-on(语法糖
@)监听子组件发布的事件,拿到子组件修改过的数据
<template>
<div class="parent-box">
<Child :data="parentData" @change="handleChange" />
</div>
</template>
<script setup>
import { reactive } from 'vue';
import Child form './Child.vue';
const parentData = reactive({
data: {
name: '',
age: '',
height: '',
}
})
const handleChange = (value) => {
console.log('经过子组件修改过的数据', value);
parentData.data = value;
// ....其他的逻辑处理
}
</script>
子组件
- 利用Element-Plus框架举例,v-model双向绑定修改_formData的值
<template>
<div class="child-box">
<el-form :model="_formData">
<el-form-item>
<el-input v-model="_formData.name"/>
</el-form-item>
<el-form-item>
<el-input v-model="_formData.age"/>
</el-form-item>
<el-form-item>
<el-input v-model="_formData.height"/>
</el-form-item>
<el-form-item>
<el-button @click="handleClick>确认</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script setup>
import {computed, defineProps, defineEmits } from 'vue';
const props = defineProps({
formData: {
type: Object,
default: () => {
return {
name: "",
age: "",
height: ""
}
}
}
})
const emits = defineEmits(['change']);
const _formData = computed(() => {
return props.formData.data;
})
const handleClick = () => {
emits('change', _formData);
}
</script>
补充:利用v-model实现子组件修改父组件的数据
Vue 3 引入了
v-model的新用法,允许子组件修改父组件传递的参数。
父组件
- 利用v-model修饰要传递给子组件的参数
<template>
<ChildComponent v-model:num="num" />
</template>
<script setup>
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';
const num = ref(0);
</script>
子组件
- 通过发布
update:num事件,修改父组件的数据
<template>
<input type="number" v-model="props.num" @input="updateNum" />
</template>
<script setup>
import { defineProps, defineEmits } from 'vue';
const props = defineProps({
num: Number
});
const emit = defineEmits(['update:num']);
const updateNum = (value) => {
emit('update:num', value);
};
</script>