qadan 发表于 2024-1-11 11:03

vue3父子组件为什么会实时传值?

本帖最后由 qadan 于 2024-1-11 13:36 编辑



图1是父组件,图2是子组件


现在的情况是:点击图 1设置,会打开图2子组件,输入完参数后直接关闭子组件,没有点确定,但是这个参数也传给了父组件(查看详情就是子组件传过来的)


我的需求是:必须要在图 2点确定,才会把参数传给父组件







父组件
<DynamicField title='设置GET参数' :data="nodeData.get_params"
                        @array-to-parent="emitToParent"/>
子组件
<template>
<!--传入 get_params/post_params,返回参数数组-->
<a-button type="primary" @click="showModal">设置</a-button>
<!--模态框-->
<a-modal v-model:open="modalStatus" :title="props.title" @ok="submitForm">
    <a-form
      ref="formRef"
      name="dynamic_form_item"
      :model="Form"
      v-bind="formItemLayoutWithOutLabel"
    >
      <a-form-item
          v-for="(params, index) in Form.paramss"
          :key="params.key"
          v-bind="index === 0 ? formItemLayout : {}"
          :label="index === 0 ? null : ''"
          :name="['paramss', index, 'value']"
      >
      <a-input
            v-model:value="params.paramskey"
            placeholder="请输入key"
            style="width: 20%; margin-right: 8px"
      />
      <a-input
            v-model:value="params.value"
            placeholder="请输入参数"
            style="width: 55%; margin-right: 8px"
      />
      <a-switch v-model:checked="params.status" style=" margin-right: 10px"/>

      <MinusCircleOutlined
            v-if="Form.paramss.length > 1"
            class="dynamic-delete-button"
            @click="removeparams(params)"
      />
      </a-form-item>
      <a-form-item>
      <a-button type="dashed" style="width: 60%" @click="addparams">
          <PlusOutlined/>
          新增参数
      </a-button>
      </a-form-item>
    </a-form>
</a-modal>

</template>
<script setup>
import {reactive, ref, defineEmits, onMounted} from 'vue';
import {MinusCircleOutlined} from '@ant-design/icons-vue'
import {message} from 'ant-design-vue'


const formRef = ref();
// 模态框状态
const modalStatus = ref(false);
// 开启模态框
const showModal = () => {
modalStatus.value = true;
};
const props = defineProps({
title: String,//标题
params: String,//get_params/post_params
data: Object,//数组
})
onMounted(() => {
Form.paramss = props.data
// console.log(props.data)
})
const formItemLayout = {
labelCol: {
    xs: {
      span: 24,
    },
    sm: {
      span: 24,
    },
},
wrapperCol: {
    xs: {
      span: 24,
    },
    sm: {
      span: 24,
    },
},
};
const formItemLayoutWithOutLabel = {
wrapperCol: {
    sm: {
      span: 24,
    },
},
};
// 表单
const Form = reactive({
paramss: [],
});
const submitForm = () => {
formRef.value
      .validate()
      .then(() => {
      console.log(11111111111111111)
      // emit('array-to-parent', Form.paramss);
      message.success('设置成功')
      modalStatus.value = false
      })
      .catch(error => {
      console.log('error', error);
      });
};
const removeparams = item => {
const index = Form.paramss.indexOf(item);
if (index !== -1) {
    Form.paramss.splice(index, 1);
}
};
const addparams = () => {
Form.paramss.push({
    paramskey: '',
    value: '',
    status: true,
    key: Date.now(),
});
};
</script>
<style scoped>
</style>

linguo2625469 发表于 2024-1-11 11:32

Form.paramss = props.data
你这里直接传递的是对象的地址,修改Form.params相当于修改了props.data,你应当把子组件内的数据独立维护 而不是直接=父组件的
如果实在要=那你就深拷贝一下 最简单的方法:Form.paramss = JSON.parse(JSON.stringify(props.data))

无常方便面 发表于 2024-1-11 11:22

虽然我不知道为啥,但我知道用深拷贝就解决问题

kof21411 发表于 2024-1-11 11:24

onMounted(() => {
Form.paramss = props.data
// console.log(props.data)
})
如果要按你的需求,这里不要直接引用,应该浅拷贝一下
提交时再emit给父组件更新

qadan 发表于 2024-1-11 11:43

linguo2625469 发表于 2024-1-11 11:32
Form.paramss = props.data
你这里直接传递的是对象的地址,修改Form.params相当于修改了props.data,你应 ...

我使用了深拷贝解决了这个问题,但是我的父组件是赋值给了别的变量,我更改了又出现实时传值的情况了,现在我使用了深拷贝,但是没有点击子组件确定,又会实时传值
<DynamicField title='设置GET参数' :data="nodeData.get_params"
                        @array-to-parent="emitToParent"/>

const emitToParent = (arrayFromChild) => {
nodeData.get_params = arrayFromChild
console.log(arrayFromChild)
}

sunzhw 发表于 2024-1-11 13:11

深拷贝可以解决

masonjs 发表于 2024-1-11 13:19

deepClone 深度拷贝一下

爱吃鹅肉饭 发表于 2024-1-11 15:15

兄弟在子组件里你不应该直接把父组件的传的值直接用,可以考虑在子组件定义新的变量来承接传的值,同时操作也操作这个新的变量,如果需要更改父组件的状态,可以emit事件去更改。
vue是单向数据流的,最好遵守这个规则

qadan 发表于 2024-1-11 20:50

爱吃鹅肉饭 发表于 2024-1-11 15:15
兄弟在子组件里你不应该直接把父组件的传的值直接用,可以考虑在子组件定义新的变量来承接传的值,同时操作 ...

请问是第66行代码吗

zxyuns 发表于 2024-1-13 23:00

遇到一个抽屉组件打开的时候不执行子组件生命周期的问题?不知道怎么解决
页: [1]
查看完整版本: vue3父子组件为什么会实时传值?