JS判断对象是否发生变化,常用于监听页面表单是否修改并给出保存提示

本文主要封装方法,实现用户离开表单编辑页面时弹出提示框,若表单数据发生变化,则提示用户是否保存当前页面的信息,如图:

封装方法:

/**
 * 比较俩个对象之间的差异,项目中多处用到监听表单数据是否改动,故封装此方法
 * 如果数据改动,则返回新旧对象记录改动字段的新旧值
 *
 * by wang
 * */
export function diffObj(obj1, obj2) {
  function getTypeByObj (obj) {
    return Object.prototype.toString.call(obj).match(/^\[object ([a-zA-Z]*)\]$/)[1];
  }
  function isEmptyObject (obj) {
    for (let key in obj) {
      return false;
    };
    return true;
  }
  if (!obj1 || isEmptyObject(obj1) || !obj2 || isEmptyObject(obj2)) {
    return null;
  }
  let diffRes = {
    old_val: {},
    new_val: {}
  };
  for (let k in obj2) {
    // 判断数据类型是否一致
    if (getTypeByObj(obj2[k]) === getTypeByObj(obj1[k])) {
      // 比较 “Array”和“Object”类型
      if (getTypeByObj(obj2[k]) === 'Array' || getTypeByObj(obj2[k]) === 'Object') {
        const diffData = diffObj(obj1[k], obj2[k]);
        if (!isEmptyObject(diffData)) {
          diffRes.old_val[k] = diffData.old_val;
          diffRes.new_val[k] = diffData.new_val;
        }
      } else if (obj1[k] !== obj2[k]) { // 比较其他类型数据
        diffRes.old_val[k] = obj1[k];
        diffRes.new_val[k] = obj2[k];
      }
    } else {
      if ([undefined, null, ''].includes(obj1[k]) && [undefined, null, ''].includes(obj2[k])) {
        // 这三类数据可视为相等,不做处理
      }else {
        diffRes.old_val[k] = obj1[k];
        diffRes.new_val[k] = obj2[k];
      }
    }
  }
  // 若没有变化,返回null
  if (isEmptyObject(diffRes.old_val) || isEmptyObject(diffRes.new_val)) {
    return null;
  }
  return diffRes;
}

如果返回值为null,则代表没有改变,否则返回改变的属性和值,如图:

脚踏实地行,海阔天空飞~

### 实现Element UI编辑按钮保存对话框修改内容更新页面显示 为了实现点击Element UI的编辑按钮后,在`dialog`中修改的内容能够被成功保存使页面数据显示最新的更改,可以按照如下方法操作: #### 定义数据模型与初始状态 首先定义好用于存储表单字段的数据对象以及控制`dialog`显隐的状态变量。 ```javascript data() { return { dialogFormVisible: false, formLabelWidth: '120px', formData: { // 表单数据初始化 name: '', region: '' }, originalData: {} // 原始数据副本,防止误操作影响原始数据 }; } ``` 当用户触发编辑动作时(比如通过列表中的某项),获取该项的具体信息填充到`formData`中作为默认值展示给用户的同时也复制一份至`originalData`以便后续对比是否有实际改动[^1]。 #### 打开Dialog逻辑处理 在打开`dialog`之前准备好待编辑的信息。假设有一个名为`editItem`的方法负责接收当前选中的条目ID或其他唯一标识符来加载对应详情。 ```javascript methods: { editItem(id) { axios.get(`/api/items/${id}`) .then(response => { const item = response.data; Object.assign(this.formData, item); this.originalData = JSON.parse(JSON.stringify(item)); this.dialogFormVisible = true; }); } } ``` 这里使用了`axios`发起HTTP请求模拟从服务器端拉取具体记录的过程;利用`Object.assign()`将返回的对象属性赋值给`formData`从而完成界面预览效果;而深拷贝(`JSON.parse(JSON.stringify())`)则用来创建独立于源数据之外的新实例供比较用途[^2]。 #### 提交变更后的验证与提交流程 对于确认保存的操作,则需先校验输入合法性再决定是否继续向后台发送更新指令。如果一切顺利的话就执行相应的网络调用将响应结果反馈出来。 ```javascript handleConfirm() { if (this.validateFormData()) { let hasChanges = !_.isEqual(this.formData, this.originalData); // 判断是否存在差异 if (!hasChanges) { alert('未做任何修改'); this.handleClose(); return; } axios.put('/api/update', this.formData) .then(() => { this.$message({ message: '保存成功!', type: 'success' }); // 更新视图上的旧版本为最新版 _.assignIn(this.originalData, this.formData); this.handleClose(); // 触发父级组件重新渲染或局部刷新机制以反映变动 this.$emit('refreshList'); }) .catch(error => console.error(error)); } } validateFormData(){ /* 验证逻辑 */ return true; // 或者基于实际情况返回布尔值表示是否有效 } ``` 上述代码片段展示了如何判断是否有实质性的变化才去尝试同步远程数据库,同时也包含了简单的错误提示和正面通知消息。另外值得注意的是最后两行关于关闭模态窗口的动作还有通知外部环境发生改变的通知方式[^3]。 #### 关闭Dialog清理工作 无论何时只要涉及到隐藏弹窗都应当记得重置内部控件回到最初设定好的样子以免残留上次交互痕迹干扰下次正使用体验。 ```javascript closeForm(){ this.$refs['form'].resetFields(); // 清除表单项样式类名等附加标记 this.dialogFormVisible = false; // 如果有必要还可以在此处释放其他资源或者撤销监听器绑定关系 } ``` 此部分主要涉及到了清空所有已填写过的资料让其恢复成空白状态等待下一轮互动的到来。同时设置可见性标志位告知UI层不再呈现该浮层结构。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值