当前位置: 首页 > 知识库问答 >
问题:

vue3 - 实现编辑当前行内容并保存修改功能时,为什么数据传着传着就变了?

小牛23011
2024-06-22

为什么数据传着传着变了?

页面结构

  • 组件A

    • 组件B1 => 用于设置过滤条件和进行过滤
    • 组件B2 => 表格,显示过滤的结果,表格中还有一个列可以用于操作对应行数据的编辑和删除
    • 组件B3 => 弹出编辑当前行的表单

我在实现编辑当前行内容并保存功能的时候遇到了些问题,以下是我的实现思路和问题。

在组件A中我声明了一个响应式数据,用于跟踪当前行的数据

const editingEquipmentLedgerForm = ref();function setEditingEquipmentLedgerForm(newValue) {  editingEquipmentLedgerForm.value = newValue;}

还有一个方法用于处理点击编辑按钮事件,它将会被传给组件B(表格显示)

function handleEdit(idx, row) {  // todo: 编辑当前行  console.log("edit current row: ", idx, row);  setEditingEquipmentLedgerForm({...toRaw(row)});  console.log("handleEdit: editingEquipmentLedgerForm: ", editingEquipmentLedgerForm);  // 打开编辑弹窗  openEditEquipmentLedgerDrawer();}

当前编辑的行数据会被传给组件B3(编辑弹窗),当我们打开编辑弹窗的时候,对应行的内容就显示在弹窗中的表单里了。

 <EditEquipmentLedgerDrawer    :startLoading="startLoading"    :endLoading="endLoading"    :postEditedEquipmentLedger="postEditedEquipmentLedger"    :editingEquipmentLedgerForm="editingEquipmentLedgerForm"    :closeEditEquipmentLedgerDrawer="closeEditEquipmentLedgerDrawer"    v-model:showEditEquipmentLedgerDrawer="showEditEquipmentLedgerDrawer"  />

但是当我修改之后,点击保存的时候,就报错了。从我打印的数据可以看到当前修改行的数据变成undefined了。

async function saveEditedEquipmentLedger(formInstance) {  // todo: 保存新的设备台账信息  if (!formInstance) return;  console.log("formInstance data: ", formInstance);  await formInstance.validate(async (valid, fields) => {    console.log("validate form: ", valid, fields);    if (valid) {      console.log("submit");      // todo: 需要对表单数据进行处理      try {        console.log("editingEquipmentLedgerForm: ", editingEquipmentLedgerForm);        postEditedEquipmentLedger(extractEditedEquipmentLedgerFormData(editingEquipmentLedgerForm));        // 模拟: 上传加载,提示上传成功,然后关闭drawer        startLoading();        await sleep(1);        endLoading();        ElMessage({          message: "设备台账修改成功,您现在可以点击查询获取最新的数据了!",          type: "success",          duration: 1000        })        closeEditEquipmentLedgerDrawer();        formInstance.resetFields();      } catch (error) {        ElMessage({          message: `设备台账修改失败 ${error.message}`,          type: "error",          duration: 1000        })      }    } else {      // 提示验证失败      console.log("error submit", fields);    }  })}

image.png

image.png

  • 为什么会出现这样的问题呢?该怎么解决呢?
  • 我实现编辑保存的方式合理吗?这个组件划分的合理吗?参数传递合理吗?是不是把简单问题变得复杂了?

附:

  • github
  • stackblitz

共有2个答案

酆出野
2024-06-22

这里给的默认值是undefined
image.png
所以子组件初始化接受的这个值就是undefined
image.png
因为你组件里的editingEquipmentLedgerForm和传过去的editingEquipmentLedgerForm没有关联关系,所以组件里的editingEquipmentLedgerForm没有随着父元素的editingEquipmentLedgerForm改变而改变。

你可以使用const props = defineProps(...);声明总的props,在需要的地方使用props.xxx取值。或者在EditEquipmentLedgerDrawer组件上使用v-if,在openEditEquipmentLedgerDrawer的时候在渲染这个组件

慕容渊
2024-06-22

没仔细看,提醒两个点

  1. console.log(obj) 的输出不是当时的值,而是在查看的时候 obj 的值(尤其是属性)。如果想输出当时的时候,用 console.log(JSON.stringify(obj)),先序列化出来再输出,或者只取其中部分属性(取到原始类型为止)输出
  2. 如果一个对象在使用的时候不是预期,有可能是在其他地方修改了。一般传递对象的时候,都是传递的对象的引用。既然是引用,那在某个地方修改了属性值,所以通过引用访问的属性都是修改后的。如果想不受影响,需要使用深拷贝(或一定深度的拷贝)
 类似资料:
  • 本文向大家介绍jQuery+PHP实现可编辑表格字段内容并实时保存,包括了jQuery+PHP实现可编辑表格字段内容并实时保存的使用技巧和注意事项,需要的朋友参考一下 本例适用场景:当查看详细资料,如用户详情信息,发现其中某几个字段信息需要修改,可直接点击该字段内容进行修改,节约了用户时间,(传统的做法是进入一个编辑页面,列出所有编辑的字段信息,即使你只需要编辑其中一两个字段内容,然后点击提交)提

  • 问题内容: 使用什么是能够编辑内容的最佳方法? 在我理想的情况下, 添加的 生日将是一个超链接,点击该链接将显示一个编辑表单-与带有更新按钮的当前添加表单相同。 实时预览(插播) HTML: App.js: 问题答案: 您应该将表单放在每个节点内,分别使用和启用和禁用编辑。像这样: 这里的关键点是: 我已将控件更改为本地范围 已添加到,因此我们可以在编辑时显示它 添加了带有的,以便在编辑时隐藏内容

  • 本文向大家介绍vue el-table实现行内编辑功能,包括了vue el-table实现行内编辑功能的使用技巧和注意事项,需要的朋友参考一下 最近做一个vue前后端分离的项目,前端框架用element ui,在 使用 el-table 的过程中,需要实现行内编辑,效果大概是这样: 分为下面几个步骤: (1) 自定义 el-table 的表头(即添加 “新增” 按钮): 表头自定义了一个“添加”按

  • 问题内容: 我正在尝试使用以下代码将一些JSON发布到具有cURL的Web服务: 我得到以下回报: string(282)“ HTTP / 1.1 200 OK服务器:Apache-Coyote / 1.1 Access-Control- Allow-Origin:*内容类型:text / plain内容长度:120日期:2011年3月18日,星期五:19:03:23 GMT {“ code”:“

  • 我可以从数据库中获取数据并将其存储在中。所有工作都很好,但是如果我从表中编辑数据并按enter键,数据就不会编辑。 值更改后不会在表中重写。 构造函数和getter/setter

  • 本文向大家介绍ajax实现修改功能,包括了ajax实现修改功能的使用技巧和注意事项,需要的朋友参考一下 这段时间在做项目,发现自己忘得好快呀,幸亏有博客园帮我记着呢,整理博客园简直不要太重要了哦 因为做的是一个内部管理系统,只用了一个主页面,所有的都不允许整个网页刷新,所以我们只能用ajax 来做,当然刚开始做也走了很多的弯路,最终还是做出来了 这点还是比较欣慰的 今天要整理一下ajax实现修改功