对象扁平化

因为开发需要,要将前后端交互参数 json 对象扁平化处理,于是抽象了一个工具函数。

实现方法参考了

https://segmentfault.com/q/1010000007039588

参考方法

export function jsonFlatten(data) {
  var result = {}
  function recurse(cur, prop) {
    if (Object(cur) !== cur) {
      result[prop] = cur
    } else if (Array.isArray(cur)) {
      for (var i = 0, l = cur.length; i < l; i++) { recurse(cur[i], prop + '[' + i + ']') }
      if (l === 0) { result[prop] = [] }
    } else {
      var isEmpty = true
      for (var p in cur) {
        isEmpty = false
        recurse(cur[p], prop ? prop + '.' + p : p)
      }
      if (isEmpty && prop) { result[prop] = {} }
    }
  }
  recurse(data, '')
  return result
}

页面打印

总结:该方法拉平了对象,同时保留了层级和所属关系,应该是为了回溯回去。

因为不符合开发需求,所以修改了下。

改动地方:recurse(cur[p], prop ? prop + '.' + p : p) 改为 recurse(cur[p], p)

修改后方法

实现如下:

export function jsonFlatten(data) {
  var result = {}
  function recurse(cur, prop) {
    if (Object(cur) !== cur) {
      result[prop] = cur
    } else if (Array.isArray(cur)) {
      for (var i = 0, l = cur.length; i < l; i++) { recurse(cur[i], prop + '[' + i + ']') }
      if (l === 0) { result[prop] = [] }
    } else {
      var isEmpty = true
      for (var p in cur) {
        isEmpty = false
        recurse(cur[p], p)
      }
      if (isEmpty && prop) { result[prop] = {} }
    }
  }
  recurse(data, '')
  return result
}

页面应用

handleSubmit() {
      this.userForm.roleId = this.userForm.roles[0].id
      console.log(this.userForm)
      const data = jsonFlatten(this.userForm)
      console.log(data)
      if (this.dialogType === 'edit') {
        this.updateUser(data)
      } else {
        this.addUser(data)
      }
},

打印

总结:方法完全拉平了对象。

不过需要注意,json 对象中的数组元素命名,不要和外面的键名重复了。

如:roles[0].id 还是改为 roles[0].roleId 比较安全,避免同名覆盖。例子中 info 对象中的 id 覆盖了 roles 数组中的 id。

最佳实践 

提前处理数据

在表单回显数据前,先处理好表单数据,而不是在最后提交表单前修改。

handleEdit(scope) {
      this.dialogType = 'edit'
      this.dialogVisible = true
      var res = deepClone(scope.row)
      // 处理用户的角色数组为空的情况
      if (res.roles.length === 0) {
        res.roles.push({
          roleId: '',
          roleName: ''
        })
      } else {
        res.roleId = res.roles[0].id
        res.roleName = res.roles[0].name
      }
      // 提前拉平对象
      this.userForm = jsonFlatten(res)
},
handleSubmit() {
      if (this.dialogType === 'edit') {
        this.updateUser(this.userForm)
      } else {
        this.addUser(this.userForm)
      }
},

因为表单校验

userFormRules: {

        username: [{ required: true, trigger: 'blur', message: '账户名称不能为空' }],

        password: [{ required: true, trigger: 'blur', message: '密码不能为空' }],

        confirmPwd: [{ required: true, trigger: 'blur', validator: validateConfirmPwd }]

}

 

好像不能识别嵌套对象

<el-form-item label="账户名称" prop="username">

      <el-input v-model="userForm.info.username" />

</el-form-item>

 

另外,嵌套对象在回显数据时,需要初始化数据内部每个属性,不像一层的对象,写个{}空对象即可。

defaultUser: {

        id: '',

        roleId: '',

        roleName: '',

        username: '',

        password: '',

        confirmPwd: '',

        photo: '',

        phone: '',

        email: '',

        sex: '',

        status: 0,

        brief: ''

      },

userForm: {},

 

对比

memberForm: { // 多层嵌套的对象表单需要初始值

        info: {

          realName: '',

          idCard: '',

          photo: ''

        },

        roles: []

},

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Irene1991

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值