vue3中子组件修改父组件传来的数据,导致父组件也发生变化
问题原因
-
引用类型数据传递
父组件传递对象/数组时,子组件接收的是原数据的引用,直接修改会双向影响。 -
基本类型数据安全
若传递字符串、数字等基本类型,Vue 会阻止直接修改并抛出警告。
注意:在子组件中修改父组件的数据是不对的,子组件不能修改父组件的属性,但是当父组件传给子组件的是一个对象类型(而非基本类型)时,修改子组件的数据时,父组件的数据也会发生变化,要想避免这种变化,就应进行深拷贝。
- 子组件 页面.vue
-
<script setup lang="ts"> import { ref ,reactive} from "vue"; import { cloneDeep } from 'lodash'; const props = defineProps({ msg: String, nameInfo: Object }); const localData = ref(cloneDeep(props.nameInfo)) const iphone = ref('18100000000') const showAddress = ref(true) const isEdit = ref(false) const emit = defineEmits(['zEdit','isShow']) const editInfo = () => { // props.nameInfo.age = '30'; localData.value.age='30'; iphone.value = '15100000000'; isEdit.value = true; emit('zEdit',isEdit) const isShow = '1234' emit('isShow',isShow) } </script> <template> <el-divider content-position="right">子页面</el-divider> <div> <el-form label-width="150px" label-position="left"> <el-form-item label="接受props信息:">{{msg}}</el-form-item> </el-form> <div class="mt-20"> <div class="f-r"> <el-button type="primary" plain @click="editInfo()">修改</el-button> <el-button type="primary" plain @click="showAddress=!showAddress">隐藏居住地</el-button> </div> <el-descriptions title="用户信息" size="default" :column="3" border> <el-descriptions-item label="用户名">{{localData.name}}</el-descriptions-item> <el-descriptions-item label="年龄">{{localData.age}}</el-descriptions-item> <el-descriptions-item label="手机号">{{iphone}}</el-descriptions-item> <el-descriptions-item label="备注"> <el-tag size="small">学校</el-tag> </el-descriptions-item> <el-descriptions-item label="居住地" v-if="showAddress">苏州市</el-descriptions-item> <el-descriptions-item label="联系地址">江苏省苏州市吴中区吴中大道 1188 号</el-descriptions-item> </el-descriptions> </div> </div> </template> <style scoped> .mt-20 { margin-top: 20px; } .f-r{ float: right; } .red-t{ background: #FDE2E2; color: red; } </style>
- 父页面
-
<script setup lang="ts"> import { ref } from "vue"; import DatapassZ from "./datapassZ.vue"; const msg = ref("详情"); const zedit = ref(""); const form = ref({}) interface Person { id: number; name: string; age: number; } const nameInfo = ref<Person>({ id: 1, name: "zz", age: 28 }); const zEdit = (a)=>{ console.log('子页面传回修改值',a.value); zedit.value = a } const isShow = (a)=>{ console.log('子页面传回多个值',a); } </script> <template> <el-card> <p class="right">父页面</p> <div class="card"> <div> <el-form ref="form" :model="form" label-width="150px" label-position="left"> <el-form-item label="传值信息:">{{msg}}</el-form-item> <el-form-item label="父组件的用户年龄:">{{nameInfo.age}}</el-form-item> <el-form-item label="子页面是否修改:"> <el-tag :type="zedit?'warning':null">{{zedit?'已修改':'未修改'}}</el-tag> </el-form-item> </el-form> </div> <Datapass-z :msg="msg" :nameInfo="nameInfo" @zEdit="zEdit" @isShow="isShow" /> </div> </el-card> </template> <style scoped> .right { font-size: 14px; color: #afabab; text-align: right; } </style>



浙公网安备 33010602011771号