asp.net接受表单验证格式后再提交数据_如何解析 el-form-renderer 表单渲染器1.14.0...

df998c499c3b54962605c53059672646.png

b496fd11a1164ef94fe44882f3500829.png

DEEPEXI 大前端

常人道,一入开发深似海,技术学习无止境。在新技术层出不穷的前端开发领域,有一群身怀绝技的开发,他们在钻研前沿技术的同时,也不忘分享他们的成果,回馈社区。下面,就由小水滴带大家看一下滴普大前端对新版 el-form-renderer 表单渲染器的硬核解析吧~

DEEPEXI 官方:产品介绍与技术分享

https://www. zhihu.com/org/deepexi

DEEPEXI 大前端:前端技术成果的分享

https:// zhuanlan.zhihu.com/deep exi-frontend

开源地址(欢迎点击github来贡献你的star哦 ✨)

https:// github.com/deepexi https:// github.com/FEMessage

el-form-renderer与表单

表单面临的难题

表单本质上是什么?表单用来承载业务需求的交互逻辑,表单的最终目的是提交一些特定格式的数据。

但在日常工作中,公司的业务不会停下,需求必然要跟着业务而不断演化,一个看似简单的页面表单也会变得越来越臃肿。

表单变得难以维护

拿项目交接举例子。项目交接了N手,各人都按各自的风格写代码;产品也交接了好几手,各按各的套路提需求。根本原因是代码的维护成本与业务不断变化之间的矛盾。

当表单中出现联动的需求,或者跨行之间发生制约关系时,表单代码的复杂度就会上升。随着业务需求的演变,如果代码处理的不好,会变得越来越难维护。

为什么要用el-form-renderer

el-form-renderer是基于 element-ui 封装的表单渲染器,但不局限于 element-ui 组件。

在完整继承了 element 的form表单属性的基础上进行了简单扩展,一些非表单组件或者封装的自定义组件,如图片上传、富文本等也可进行整合,从而用户能够通过使用一段预设的数据渲染出一个完整的表单。

用一句话来概括,el-form-renderer 让表单的构建与维护变得更简单了。

el-form-renderer(表单渲染组件)

ad3409bb6212ea6eaa4179165ce37793.png

issues:

a271eac5aaad247d01371a8434ae7277.png

el-form-renderer 1.14.0 重磅发布

el-form-renderer 1.14.0 : 支持 v-model

版本更新主要带来了 v-model 功能,并加入了 cypress 做 e2e 测试来护航。下面一起来看看开发小哥此时版本迭代的心路历程吧~

功能:v-model

这次 feature 版本更新,主要是为了 v-model 功能开展的。其可以解决以下问题:

  • 不再需要对 ref 操作 updateForm、getFormValue 来与数据交互。
  • 可以直接观察当前的表单数据变更,来进行特定操作。

后续对 valid 状态,也通过 prop + sync 的形式管理,基本就可以脱离对 ref 的依赖。

提升代码质量

由于 el-form-renderer 已经是历时两年多的开源项目,许多代码经多人转手,已经存在以下问题:

  • 不合适的写法。比如大量使用 render 函数;
  • 大量使用 mixin 和字符串拼接来调用功能,开发者难以定位调用链条。比如在生成 option 数组时;
  • 废弃的功能。比如不太好用的 enableWhen 等等;
  • 没有注释的 hack。比如尝试兼容 select, radio & checkbox 用法的代码(在1.14.1版本修复)。

所以提高维护性也是本次迭代的重中之重。开发从此开始。

测试

第一步,加入自动化测试。先前,项目中已经引入了 jest 做单元测试。单元测试可以保证一些核心逻辑的稳定性,比如一些数据处理、转换函数的输入输出意图。

但是其没有办法测试真实示例使用起来时的稳定性,比如用户真正在表单中输入值、点击重置按钮的行为。

此前,行为的稳定性只能依赖开发者和 review 人员手动对示例进行测试。

现在,项目使用 cypress 来对每个示例的行为进行自动化测试。这样开发者可以放心重构和添加功能,同时轻松维护过往表现的一致性。

如何写行为测试

重点应当关注用户行为层面,而不是代码输出层面。

比如,应当测试:

  • 用户输入文本。
  • 确认文本框中有该内容。
  • 用户点击提交按钮。
  • 确认窗口内显示成功信息。

而不是:

  • 用户点击按钮。
  • 等待某个接口有返回内容(测试按钮有没绑定到函数,和接口是否正常)。

重构

重构的主要成果是:

  • 用 template 重构了所以 render 函数。代码更符合 vue 规范写法。
  • 移除了 mixin。将相关功能转化成纯函数,并补充单元测试用例。
  • 层级调整。vue 组件移到 components 目录下;js 文件移到 util 目录下。
  • 优化函数命名。比如使用具体的 removeDollarInKey 替代 transformItem。
  • 梳理了关键复杂点的逻辑,并提取成纯函数,补充单元测试。
  • 补全了所有关键示例的端测试。
其中补充的单元测试包括:transformInputFormat(用 inputFormat 处理初始和 updateForm 的值);transformOutputFormat (用 outputFormat 处理 getFormValue 的值);collect (从 content 中搜集 options 和初始 value。

inputFormat & outputFormat

这次重构的最大难点,就是处理 inputFormat、 outputFormat、group 与表单值 value 的逻辑。直接给出定义的话:

  • 每个表单项的 inputFormat 接受当前 这一层(group) 的值,返回 当前项的值。
  • 每个表单项的 outputFormat 接受 当前项的值 ,返回的值先判断是不是对象:
    • 如果不是,返回值视作 当前项的值。
    • 如果是,返回值将整体覆盖到 这一层(group) 的值。

具体看如下示例。使用到的同学请务必注意其用法。

inputFormat

重构前:

/ content 配置
{
  id: 'a',
  inputFormat: v => v + 1 // 接受传入值,返回新值
}
//
this.$refs.form.updateForm({a: 1})
this.$refs.form.getFormValue() // {a: 2}

重构后:

// content 配置
{
  id: 'a',
  inputFormat: formValue => formValue.notA // 接受整个 formValue 来处理!
}
//
this.$refs.form.updateForm({notA: 1})
this.$refs.form.getFormValue() // {a: 1}

outputFormat

重构前:

// content 配置
[
  {
    id: 'a',
    default: 1,
    outputFormat: a => a + 1 // 接受内部值,返回处理过的值
  },
  {
    id: 'b',
    default: {c: 2},
    outputFormat: b => (b.c += 1, b)
  },
]
//
this.$refs.form.getFormValue() // {a: 2, b: {c: 3}}

重构后:

// content 配置
[
  {
    id: 'a',
    default: 1,
    outputFormat: a => a + 1 // 这个的理解是对的
  },
  {
    id: 'b',
    default: {c: 2},
    outputFormat: b => (b.c += 1, b) // 当返回值是对象时,会整体覆盖到上一层!
  },
]
//
this.$refs.form.getFormValue() // {a: 2, c: 3}

开发功能:v-model

开发过程

  • 新增属性 form,作为对外 v-model 的属性。
  • 在 watch 里对接数据流水线:
    • 监听 form、content 的变更 -> 搜集初始值 --inputFormat--> value
    • 监听 value 的变更 --outputFormat--> form
  • 写新的示例 v-model.md 和测试 v-model.spec.js(参考 basic 即可)。

测试流程

  • 输入各种 input、select、radio。
  • 检查输入后 v-model 的状态。
  • 点击 reset 按钮,v-model 回到初始状态。

发现问题

  • 在模拟点击 reset 按钮时,当 cypress 测试里点击重置按钮, reset 未生效。
  • 手动在 cypress 的调试浏览器中点击按钮,reset 生效。
  • 在普通浏览器中点击按钮,reset 生效 。
  • 在 reset 函数里打点,此时 reset 函数在以上情况中 都有被正常调用。
  • 尝试在 cypress 代码中先等待1秒再点击按钮,reset 未生效。
  • 尝试在 cypress 代码中连续写两次 click 按钮操作,reset 生效。
发现有可能是 cypress 的问题,标明注释说明手动测试成功,连点两次是 hack 写法。

解决问题

review 了下原本的 resetFields 逻辑,发现了如下问题

  • reset 后 el-select 报错的 bug。
  • reset 后,value 监听器监听不到改变,因为 el-form 的实现机制中改了 value 后没有 emit input 事件。
  • 如果在监听器上加 deep: true,则会发现新值和旧值相同。原因暂时不明。

在发现以上问题基础上,对代码进行如下修改

  • 在 form、value 监听器中用 lodash 的 isequal 判断前后的值,有变更时才 emit input 事件。
  • 参考 el-form 机制在内部实现了 resetFields:用的是 mounted 时传入的值,然后清除校验错误信息。

解决了用例异常的问题,有如下总结

  • 仍没有弄清楚为什么 cypress 的模拟操作代码调用的 resetFields 没有正常运作。
  • 疑似 cypress 的问题导致 resetFields 的其他问题被发现。
  • 重视测试的心以一种特别的方式让组件得到了回报。

关于初始状态

值得一提的是,目前 resetFields 所认定的 初始状态,是在组件 mounted 阶段时 v-model 的值。这点与 element 一致,因为一些 element 表单组件,会在 created 阶段,在传入的 value 值不合法时会重新 emit 一个正确的初始值给到 v-model。比如:

  • 开启了 multiple 的 el-select,会修正初始值为 [] 。
  • el-checkbox,会修正初始值为 [] (由 el-form-renderer 实现,原生是没有的)。

更新文档

此次更新顺带修复了一些老示例的错误用法。可能不少 el-form-renderer 的用户还不了解,el-form-renderer 的 disabled 属性,统一在配置最上层级设置:

// content 定义
[
  {
    disabled: true, // 在这里设置
    el: {
      disabled: true // 无效
    }
  }
]

意外之喜

文档: https:// femessage.github.io/el- form-renderer/#/Demo/content

在写 v-model 数据流水线时,因为把 content 也融入在其中,所以现在可以在运行时修改 content,并观测表单变化。

快速咨询

登陆下方链接申请售前咨询,联系人姓名中加上推荐码 deepexi@zhihu 将有专人联系开通。

全场景数据智能引擎​cloud.deepexi.com

往期推荐

全渠道数字化营销平台 DEEPEXI DM​mp.weixin.qq.com
2eabda5ca1496fb58f9b2f51da0d446b.png
企业级研发效能利器 DEEPEXI DevOps​mp.weixin.qq.com
e2f3e3e19dd8c254036247f5eaafb909.png
企业级前端全链路开发服务平台:DEEPEXI Serverless(A20)​mp.weixin.qq.com
1f0d2af4cee87245dbdfac83b034dbb3.png
周期购自动派单率不高?可能是你不知道这个解决方案!​mp.weixin.qq.com
4b59e48f27113478382124267b1b35d1.png

更多内容

全场景数据智能引擎​cloud.deepexi.com
DEEPEXI是滴普科技公司面向企业数字化领域打造的云原生智能平台,定位于企业数字化引擎,为企业提供数字化全栈解决方案。滴普科技致力于互联网/大数据/人工智能/物联网领先技术产品解决方案的研发和实施,是领先的全场景数据智能服务商。

cbbcc4c95459a97b51c50fa8c1d16c43.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值