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消息提示,删除成功,调用请求数据函数来更新列表

你可能感兴趣的:(VUE3,javascript,前端,vue.js)