项目总结:简简单单的“报名表单”引发的全方位思考

2,069 阅读7分钟

前段时间做了个新需求,给某某网站做一个活动报名表单。需求简单清晰明了!至少我当时是这么认为的。但做完之后发现需要注意的细节蛮多的,因此写下此篇文章来总结复盘一下~ 🥳

需求背景:

该网站需要一个通用性比较好的表单,而我所在的团队是技术中台,恰好有一套基于 arco-design 基础组件封装好的且通用性很强的表单组件。 所谓通用性好,即可以以参数的方式给表单组件传入特定格式的json来生成对应的表单,例如:

{
   "formItems": [
       {
           "keyname": "user_name",
           "label": "1. 你的姓名是?",
           "inputWidgetType": "Input",
           "required": {
               "type": "bool",
               "value": true
           }
       },
        {
          "keyname": "expectation",
          "label": "2. 你对此活动的期待是?",
          "inputWidgetType": "TextArea",
          "inputWidgetProps": {
            "maxLength": 2000,
            "placeholder": "请输入",
            "showWordLimit": true
          }
        }
   ]
}
<CommonForm formItem={JSON的内容} />

生成的表单长这样: 截屏2022-06-27 21.21.36.png 当然用json不仅仅可以生成单文本框、多文本框,还可以生成单选、多选等各种类型的表单输入框,总而言之,这个表单组件的通用性非常强!(找个时间也去研究一下这个组件是怎么写的~)

回归正题,这次我所做的表单功能如下:

表单的功能:

  1. 活动开始
  2. 活动报名开始
  3. 用户填写表单
    1. 表单具备校验功能
    2. 表单具备实时保存功能, 并且中途离开该表单页面,浏览器会由弹窗提示
    3. 提交按钮
  4. 用户修改表单(当用户提交表单之后,想修改之前填写的表单)
    1. 表单头部提示:当前正在修改表单
    2. 表单具备校验功能
    3. 取消实时保存填写内容的功能, 打开页面获取到的是用户上一次提交到服务端的表单数据, 中途离开表单,会由弹窗提示
    4. 更改按钮
  5. 报名活动结束
    1. 表单头部提示:当前报名活动已结束,禁止填写表单
    2. 表单禁止填写
    3. 更改按钮按钮消失

一些比较坑的地方:

  1. 及时获取数据 --> useState:有待补充

不好修改样式 (arco design) 由于这次项目,表单是使用 react 写的,并且这个表单组件是基于arco-design生成的组件,样式效果是arco-design的, 我需要把表单放在用vue写的网站里,而vue的网站里是没有使用arco-design的。然后设计师在设计表单ui稿的时候还是以该网站的设计风格来设计该表单,导致我在修改该表单的样式时候不断和设计师进行样式妥协。苦不堪言~

部署到线上,耗时太久 项目已经上线完成,但是出现了一个问题即在线上环境发现bug,我把bug修复后同事重新部署到线上环境,这个部署过程花费了1个半小时,同事这一个半小时就得在这里一直等待线上的测试效果。显然,这样的操作是十分浪费人力的,以及用户要在较长时间之后才能看到bug修复后的网页。 这个部署是否能够得到较好的优化,将1个半小时的部署时间缩短,有待期待~

长字符链接的换行

在表单的顶部有例如这样的表单介绍: 截屏2022-06-28 13.40.57.png 产品认为,“去掘金社区”后面不能留太多空白,应该有如下图效果:

截屏2022-06-28 13.41.06.png

解决方法如下:

word-wrap: break-word;
word-break: break-all;

以及使用white-space: pre-line;来处理字符串内容空白换行问题。

做的过程中忽略之处:

表单的单文本框和多文本框的混用问题 在这次表单需求里,我按照示意图的表单来设计的json,导致出现了一个问题,邮箱填写、学校填写全是多文本框,并没有过多的思考这样的输入框的是否合理。 截屏2022-06-28 13.23.08.png

当然我的这种错误操作也被同事指正出来:

截屏2022-06-28 13.24.23.png 下次我得多注意注意才行~

localStorage 用cache的原因 账号切换问题 --> 本地数据保存

没有及时在群里同步问题 在这次项目开发过程中,这个表单组件出现了一些bug, 但是我没有及时的在项目群里同步该问题导致其他人以为进度顺利,实际上,这次修复这个bug花了一定的时间,而因为大家的信息不对称导致进度被拉慢

userID 字符串类型 这是一个提醒自己的小知识,因为我习惯把id设置为number类型,但是因为userId一般数字位数很大,用number类型显然不合理,应该用string类型才对!

及时提交代码 要及时上传代码到远程仓库,我发现自己有几次因为周五快下班,高高兴兴回家,连代码都忘提交到远程仓库。导致周一回到公司的时候,看见自己的代码多多少少有点不确定当前未提交的代码是否可以提交~

活动未开始的时候,点击提交无效 在测试环节,出现了一个尴尬的bug,即在活动未开始的时候,点击表单提交按钮仍能提交... 这是最开始设计代码的时候没有考虑到的事~ 下次一定要注意!

有意思的地方

将react写的表单放进vue项目里

使用的技术是vuera

中途遇见的一个坑: vuerassr 渲染这部分会有一定的缺陷(vuera这个库已经有两年没有人维护了~要慎用)

退出当前页面,浏览器会有弹窗提示

使用的技术是beforeunload 事件。 当浏览器窗口关闭或者刷新时,会触发 beforeunload 事件。当前页面不会直接关闭,可以点击确定按钮关闭或刷新,也可以取消关闭或刷新。

中途遇见的一个坑:vue的路由(vue-router)里面, beforeunload 只会对a标签链接跳转有效果,但是对于router-link的跳转是捕捉不到的。

解决办法: 使用vue-router自带的beforeRouteLeave来解决,在离开该路由前进行链接跳转的修改

beforeRouteLeave(to, from, next) {
    if (this.formChange) {
        next(false)
        window.location = to.path as unknown as Location
    } else {
        next();
    }
}

学会以mock数据的方式自由的操作各种状态

因为这个表单的状态比较多(活动前后状态、表单提交/修改状态~),为了测试我的表单能够在各种状态都能适用,起初我是找服务端的朋友帮我修改对应的数据。当然,这种方式是极其低效和尴尬的,于是我自己花了1个小时学习如何使用公司的mock插件,终于,我可以自己随心所欲的mock对应的接口数据了,效率大大提高~

后知后觉的地方:

在项目上线之后,周末我无意间看见这样一篇博客ahooks 是怎么解决用户多次提交问题? 这篇文章告诉我,对于一个表单,如果我连续快速的多次点击提交,可能会导致表单提交出错。 摊牌了,这个问题,我在写表单的时候完全没有考虑到... 当然,在这篇文章中告诉了我该怎么做,“解决这类问题的方法有很多,比如添加 loading,在第一次点击之后就无法再次点击。另外一种方法就是给请求异步函数添加上一个静态锁,防止并发产生。这就是 ahooksuseLockFn 做的事情。” 我觉得useLockFn这个钩子非常有意思,于是也自己去看了看对应的源码~ 这里就不再过多赘述了。