el-table中设置行数据联动变化时,其他列的数据延迟更新(要点击其他位置才更新)的问题解决!

有段时间没有写文章了,因为一直在忙着赶项目,每次想写什么都觉得好累,身心俱疲。可是不写又怕踩过的坑哪天又掉进去了,而且时间一长就忘了当时是怎么解决的,果然是年纪大了么…

问题描述

项目中需要做一个表格行的数据联动,修改号码,会根据输入的值进行判断是否符合规则,符合规则就能够输入;否则就提示错误信息,并将表格的值置为修改之前的值。这里我使用了自定义指令来完成校验和恢复旧值,当元素focus的时候记录值,如果提示错误就恢复刚刚记录的值。
在这里插入图片描述
实测了一下,效果杠杠的。
在这里插入图片描述
然鹅一切并不是想象的那么美好。
再多测试几个页面,发现有些页面是好的,有些页面却会出现如上图所示的奇怪现象!自定义指令修正了错误值,但是你一点击表格区域,数据就又变成了错误值!
更奇怪的是其他的几个页面却不会出现这个问题!
这奇怪的现象让我想起来原来使用事件绑定来处理数据联动和效验时,也出现过同样的怪像,当时绑定的change事件,理论上我修改完了数据,点击其他任何地方,数据都应该产生联动效果,即根据我设置的值自定计算其他的值。但是实际情况是,我必须点击一下表格中的任意区域,数据才会联动更新!!后来这种方案被boss否决了,这个问题也不了了之。

解决之道

解决问题总是容易的,不容易的是找出问题,我一定要找出这种怪像的根源。
于是在弹窗之前console了一下元素,看看元素结构。
不看不知道,一看吓一跳。
在这里插入图片描述
这里可以清楚的看到,该元素拥有一个数据属性和一个访问器属性,然而数据属性value和访问器属性_value的值居然不一样?访问器属性的值是修复后的00551235,而数据属性居然是123!!!难怪自动修复之后,再点击表格的其他区域,数值会变成123!!因为数据属性本身就是123!
那么问题又来了,为什么会出现这种情况?
其实问题应该这样问:为什么访问器属性的值和数据属性的值不同?

那么我是在哪一步赋值的00551235呢?是在提示错误,弹窗之后通过el.firstElementChild.value = oldValue来给value属性赋值的!而上图显示说明,value作为访问器属性,确实被赋值成功了!那么为什么数据属性的值却没有改变呢?

于是又是一顿折腾,终于发现原来rowData.endnumber这个属性原来并不存在,由于服务器返回的对象中,并没有endnumber这个字段,是应要求在前端获取数据之后,手动添加上去了!
而手动添加的代码居然是这样的:
在这里插入图片描述
没错,就是这里。(没错,这个坑爹的坑就是我自己埋的)
看尤大的官网,https://cn.vuejs.org/v2/guide/list.html#对象更改检测注意事项
在这里插入图片描述
八成是这个坑没错了!

在这里插入图片描述

于是使用$set来定义新增的对象属性,问题完美解决!
说来说去,还是因为自己对于vue中对象属性的新增的坑,没有足够的重视。导致了这样一个奇怪的bug。

而关于这个bug的深究,我觉得还是有点意思的,还是双向绑定的原理。因为vue双向数据绑定的原理是通过definePropoty来劫持对象属性,然后在对象属性值变动的时候,调用订阅方法,更新视图。而由于我没有使用$set方法 ,导致新增的数据属性没有被vue初始化生成劫持后的setter和getter方法,导致了后面一系列的问题o(╥﹏╥)o

el-dialog和el-table数据联动可以通过以下几个步骤实现: 1. 在el-dialog定义需要编辑的表单字段,绑定表单数据对象。 ```html <el-dialog v-model="dialogVisible" title="编辑数据"> <el-form :model="formData" ref="form"> <!-- 表单字段 --> <el-form-item label="名称" prop="name"> <el-input v-model="formData.name"></el-input> </el-form-item> <el-form-item label="年龄" prop="age"> <el-input v-model.number="formData.age"></el-input> </el-form-item> <!-- 其他表单字段 --> </el-form> </el-dialog> ``` 2. 在el-table定义展示数据,并绑定数据表。 ```html <el-table :data="tableData"> <el-table-column label="名称" prop="name"></el-table-column> <el-table-column label="年龄" prop="age"></el-table-column> <!-- 其他 --> </el-table> ``` 3. 在页面使用Vue的双向数据绑定,将el-dialog的表单数据el-table数据表进联动。 ```javascript export default { data() { return { dialogVisible: false, // 控制对话框显示隐藏 formData: {}, // 表单数据对象 tableData: [], // 数据表 }; }, methods: { editData(row) { this.formData = { ...row }; // 将选数据赋值给表单对象 this.dialogVisible = true; // 打开对话框 }, saveData() { // 保存数据逻辑 // 更新tableData对应的数据 // 关闭对话框 }, }, }; ``` 在el-dialog的编辑按钮绑定`editData`方法,当点击编辑按钮,会将选数据赋值给表单对象,并打开el-dialog对话框。 在el-dialog的保存按钮绑定`saveData`方法,当点击保存按钮,执保存数据的逻辑,更新tableData对应的数据,并关闭el-dialog对话框。 这样就实现了el-dialog和el-table数据联动
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值