多数据提交和还原-前端解决方案

博客围绕表单页面提交和编辑数据的业务场景展开。因数据量庞大,一值对应一字段不可行。提出解决方案,额外用途数据与后端定义字段,仅当前页展示的数据用对象转字符串保存。以Vue为例介绍具体实现,此方案可减少开发工作量,还提及方案中的问题及解决办法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

业务场景:

  • 表单页面提交数据保存
  • 再次打开此页面请求之前保存的数据,编辑保存

问题:

  • 数据量太大了,有几百个输入框,还有单选,多选,文本域,下拉选项等,一值对应一字段不大可行

解决方案:

  • 对于额外用途的数据(不仅仅在此页面展示),需要和后端定义明确的字段
  • 仅在当前页面展示的数据,用 对象转字符串 保存,对象用于存储只在当页展示的数据

具体实现方法(以vue为例):

原数据生产方法:用于返回一个json对象,在数据还原的时候,能找到在页面中所处的位置

function createOriginData (num) {
  const data = {}
  for (let i = 0; i <= num; i++) {
    data[i] = ''
  }
  return data
}

数据格式:

data () {
	return {
		formVal: {
									// 不需在在此定义,比如直接在页面通过 formVal.xxx 赋值的操作
			confirmStr: '', // 和后台明确定义的数据,在其他地方有用
			tmpStr: '', // 特殊情况需要定义的数据,防止页面报错
			tmpArr: [], // 用于页面的数组系列的数据
			createObj: createOriginData(10), // 用于仅在当页展示的数据
		}
	}
}

html:

// 可以开始不在formVal设置默认值
<input v-model="formVal.xxx" />

// 仅在当页展示的数据
<input v-model="formVal.createObj[0]" />
...
<input v-model="formVal.createObj[10]" />

// 明确定义的数据
<input v-model="formVal.confirmSte" />

// 防止页面报错,在用一些组件的情况下,这种场景下必须定义
<a-radio-group name="radioGroup" v-model="formVal.tmpStr">
  <a-radio value="aaa">aaa</a-radio>
  <a-radio value="bbb">bbb</a-radio>
</a-radio-group>

// 用于数组的接收的场景,比如
<a-checkbox-group v-model="formVal.tmpArr" >
  <a-checkbox value="aaa">aaa</a-checkbox>
  <a-checkbox value="bbb">bbb</a-checkbox>
</a-checkbox-group>

数据整理提交:

const formVal = Object.assign({}, this.formVal)
// 此操作主要用于在把对象转字符串
Object.keys(formVal).forEach((k) => {
	if (typeof formVal[k] === 'object') {
		formVal[k] = JSON.stringify(formVal[k])
	}
})

数据还原:

methods: {
	toRestore () {
		const _this = this
		const ajaxData // 假设此数据为ajax返回的数据,此数据的k值为之前提交数据的数据
		Object.keys(ajaxData).forEach(k => {
            if (ajaxData[k]) { // 只有当有值的情况下,才能赋值
              try {
                const obj = JSON.parse(ajaxData[k])
                _this.formVal[k] = obj
              } catch (e) {
                _this.formVal[k] = ajaxData[k]
              }
            }
       	})
	}
}

最后补充一个方法,必填数据后才能提交:

// data-no,用于标示可以为空的数据能提交, 如 <input type="text" data-no="1">
// 关于select, radio, checkbox,可以设定默认值,不在此方法中检测,或者另外检测
function checkValues (dom) {
  const inputs = dom.getElementsByTagName('input')
  for (let i = 0; i < inputs.length; i++) {
    if (inputs[i].getAttribute('data-no')) continue
    if (inputs[i].type === 'text' && inputs[i].value.trim() === '') {
      inputs[i].classList.add('border-red')
      inputs[i].focus()
      return false
    } else {
      inputs[i].classList.remove('border-red')
    }
  }
  const textareas = dom.getElementsByTagName('textarea')
  for (let i = 0; i < textareas.length; i++) {
    if (textareas[i].getAttribute('data-no')) continue
    if (textareas[i].type === 'textarea' && textareas[i].value.trim() === '') {
      return false
    }
  }
  return true
}

总结

此方案能减少 多数据表单 开发的工作量,刚开始的时候采用的是别的方案,后来项目优化想到此方案。

---------------------------这是华丽的分割线-------------------------
总结:
1,最快的方案是:JSON.stringify(obj)
2,bug

data () {
	obj: {}
}

在html中,可以 v-model=“obj.xxx”,最后数据提交
但是如果保存后还原数据再编辑(ps:js操作,obj.xxx=‘xxx’),会导致页面输入框变为不可编辑状态,还是需要在data中赋值

data()
{
	obj: {
		xxx: ''
	}
}

3,在数据还原这步,更改了取值的方法,解决超长数字转换产生的bug

watch: {
  pData (pData) {
    const formVal = this.formVal
    Object.keys(formVal).forEach(k => {
      if (pData[k]) {
        try {
          if (/(\{)|(\[)/.test(pData[k])) {
            const obj = JSON.parse(pData[k])
            formVal[k] = obj
          } else {
            formVal[k] = pData[k]
          }
        } catch (e) {
          pData[k] && (formVal[k] = pData[k])
        }
      }
    })
  }
},
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值