VUE3点击编辑时传值给弹窗
VUE3给编辑页面传值
VUE中文官网的话:
“所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。”
我对这段话的理解是,不让子组件直接使用父组件传递过来的值,根本原因是怕数据之间互相影响。
vue中修改复杂类型的数据不能直接赋值,
我采用的是Object.assign 把源对象拷贝给目标对象。
1.源对象只有一层数据
const obj1={
name:'小花'
}
const obj2={
age:1000
}
Object.assign(obj1, obj2)
console.log(obj1);//{ name: '小花', age: 1000 }
obj1.friend="小草";
console.log(obj2);//{ age: 1000 }
2.源数据有两层
const obj3={
}
const obj4={
person: {
name: '小花',
}
}
Object.assign(obj3, obj4)
console.log(obj3);//{ person: { name: '小花' } }
obj4.person.friend="小草";
console.log(obj3);//{ person: { name: '小花', friend: '小草' } }
总结:
当对象只有一层的时候,拷贝的是name:小花,gae:1000…等基本数据类型,修改源数据或修改目标数据,当然不会相互影响。
当数据有两层的时候,拷贝的是对象的引用。修改源数据或修改目标数据,之间会相互影响。
点击编辑页面我有3个做法:
父组件创建一个editInfo
,点击的时候通过 Object.assign(editInfo, row);
给editInfo
赋值。
父组件部分代码:
<template>
<el-table-column label="操作" width="100">
<template #default="scope">
<el-button type="primary" size="small" link @click="handleEdit(scope.row)">编辑</el-button>
</template>
</el-table-column>
<AddContract :title="dialogTitle" :fromParams="editInfo" :dialogFormVisible="dialogFormVisible"
:close="closeAddDayDialog" />
</template>
<script setup>
const editInfo = reactive({ saleNumber: 0 });//1.父组件定义一个变量
function handleEdit(row){
Object.assign(editInfo, row);
dialogFormVisible.value = true;
}
</script>
子组件:
方法1.直接使用editInfo
方法2.子组件创建一个addContractParams变量,watch监听到依赖变化的时候,对addContractParams赋值,之后对addContractParams这个变量进行操作
const addContractParams = reactive({
updateDate: '',//修订日期
documentType: '',//文档类型
admin: '',//管理员
operators: '',//最后操作人
})
watch(props.editInfo, (newValue) => {
Object.assign(addContractParams, newValue.value);
}, { immediate: false })
方法3.计算出一个addContractParams变量,computed 监听到依赖变化的时候,对addContractParams赋值,之后对addContractParams这个变量进行操作
const addContractParams = computed(() => {
return Object.assign(data.fromParams, props.editInfo);
});
从Object.assign
的角度来看,数据只有一层的情况下。用这三种方法的是一样的。
从执行次数和占用空间的层面上看:
直接使用editInfo拷贝了row,比一下两种情况都少在堆空间创建一个变量。
watch和computed的操作都是–> editInfo拷贝了row,
addContractParams又拷贝了editInfo。只是watch比computed少执行了一次。
如果row的某个属性值有两层,这三种方法都一样出现弊端。Object.assign() 是浅拷贝。
无论创建一个新的变量 或是 直接使用editInfo。子组件数据改变,都会立刻影响父组件数据的改变。
得出结论:
针对row数据只有一层的情况下,这三种方法,第一种算好点吧。
只是原则上不建议。
针对row数据有两层的情况下。这三种方法都危险,
解决:第一种方法在点击编辑事件的时候,进行深拷贝
后面两种都是监听到依赖发生变化的时候,进行深拷贝
方法4:
在点击编辑按钮的时候再创建子组件(v-if),如果row只有一层,在子组件的生命周期里浅拷贝一份
如果row有两层,在子组件的生命周期里深拷贝一份。
优点是,从声明周期的角度看:父组件渲染的时候,子组件不会渲染了。
父组件 beforeCreate, created, beforeCreate, 子组件 beforeCreate, created,mounted,父组件mounted
这是我的方法,当点击编辑的时候,你有什么比较好的方法可以推荐给我吗?如果我的做法不对,欢迎指出来呀
补上一个我今天看到的一个面试题吧
商品的增删改查
答:
根据接口文档获取到已有的商品列表信息(商品名称、商品价格、商品信息),进行列表渲染展示,可以对商品进行增加、删除、修改。
添加:
根据接口文档,发送添加请求,判断接口返回结果中code字段的值,值是200就使用Element-UI的message消息提示,添加成功,关闭遮罩层为false, 调用请求数据函数更新列表;否则抛出一个错误信息。
修改:
当点击修改时,弹出Element-UI遮罩层收集用户修改的数据,这里进行了一个lodash浅拷贝赋值操作(因为数据在页面上正在展示,直接修改数据会导致页面数据发生变化),点击确定的时候会把用户信息作为参数,发生修改请求,判断接口返回结果中code字段的值,如果值是200就是有Element-UI的message消息提示修改成功,关闭遮罩层为false,
调用请求数据函数更新列表;否则就抛出一个错误;
删除:
在删除的回调中可以拿到当前商品的id,那么就把id作为参数发送删除请求,判断接口返回结果中code字段的值,如果值是200就使用Element-UI的messag消息提示,删除成功,调用请求数据函数来更新列表
更多推荐
所有评论(0)