美文网首页
日常开发:近100项的巨型表单

日常开发:近100项的巨型表单

作者: 薯条你哪里跑 | 来源:发表于2019-03-04 11:51 被阅读0次
    背景:

    公司有个‘美国行’的游学项目,在筹备阶段需要收集律师们的信息来办理邀请函签证等;之前一直用的三方信息收集工具,但是考虑到数据流失问题,最后决定自己搞个小程序来收集。

    页面:
    image.png

    等等等。。手机不好截图,截个后台的图~

    开发过程:

    一开始以为就是普通的表单,select radio input datepicker 来几波就能搞定。。。但是对接了需求后发现表单项是在是太多了,不但有的还有关联关系,如:婚姻状态选了已婚才会出现子女信息和配偶信息;而且子女信息等还可以添加多个。。。。

    CALM DOWN

    补单表单项多而且还有关联关系。。总不能一个个if搞简直太low。

    于是决定处理下:

    1.将各个不同交互项抽成组件
    2.根据表单对象passData 的key 构造成新的带有配置项的 configObj
    3.对表使用for操作,在configData 中 取 passData 对应key的配置进行渲染

    成果:

    主文件代码:
    ps: template 部分只有82行,如果用component再来一层目测也就20行左右吧+

        <Form ref="materialForm" :model="passData" label-position="top">
          <div v-for="(val, key) in configObj" :key="key" v-if="!val.hide">
            <FormItem class="form-item" :label="val.label" v-show="!val.stillHide" :required="val.required" :prop="key">
              <p class="tips">{{val.tip}}</p>
              <input
                class="ivu-input"
                v-if="val.type === 'text'"
                v-model="passData[key]"
                :name="key"
                :data-vv-name="key"
                v-validate="{required: !!val.required}"
              />
              <textarea
                class="ivu-input"
                v-else-if="val.type === 'textarea'"
                v-model="passData[key]"
                :name="key"
                :data-vv-name="key"
                v-validate="{required: !!val.required}"
              ></textarea>
              <Select
                v-model="passData[key]"
                v-else-if="val.type === 'radioSelect'"
                v-validate="{required: !!val.required}"
                :data-vv-name="key"
              >
                <option value="">--请选择--</option>
                <Option v-for="item in val.list" :key="item" :value="item">{{item}}</Option>
              </Select>
              <p v-show="errorBags.has(`${key}`)" class="error">请填写{{val.label}}</p>
            </FormItem>
            <div v-if="val.showOption && val.ifOption !== undefined">
              <div
                v-for="(optItem, index) in val.ifOption.option"
                :key="`${val.ifOption.key}_${index}`"
              >
                <FormItem
                  v-for="(optVal, optKey) in optItem"
                  :key="`${val.ifOption.key}_${index}_${optKey}`"
                  class="form-item"
                  :label="optVal.label" 
                  :required="optVal.required"
                  :prop="optKey"
                >
                  <p class="tips">{{optVal.tip}}</p>
                  <input
                    class="ivu-input"
                    v-if="optVal.type === 'text' || optVal.type === 'number'"
                    v-validate="{required: !!optVal.required}"
                    v-model="passData[val.ifOption.key][index][optKey]"
                    :data-vv-name="key"
                    :name="`${val.ifOption.key}_${index}_${optKey}`"
                    :type="optVal.type"
                  />
                  <textarea
                    class="ivu-input"
                    v-else-if="optVal.type === 'textarea'"
                    v-validate="{required: !!optVal.required}"
                    v-model="passData[val.ifOption.key][index][optKey]"
                    :data-vv-name="key"
                    :name="`${val.ifOption.key}_${index}_${optKey}`"
                  ></textarea>
                  <p v-show="errorBags.has(`${val.ifOption.key}_${index}_${optKey}`)" class="error">请填写{{optVal.label}}</p>
                </FormItem>
              </div>
            </div>
          </div>
        </Form>
    

    配置文件的一部分:
    ps: 虽然配置文件有500+行😂,最好是后端返回模板

      email: {
        label: '邮箱',
        type: 'text',
        defaultVal: '无',
        required: true
      },
      recipientName: {
        label: '收件人姓名',
        type: 'text',
        required: true
      },
      recipientPhone: {
        label: '收件人联系方式',
        type: 'text',
        required: true
      },
      recipientAddress: {
        label: '收件人地址',
        type: 'text',
        required: true
      },
      // 家庭情况
      homeAddress: {
        label: '家庭住址',
        type: 'text',
        defaultVal: '无',
        required: true
      },
      fatherStatus: {
        label: '父亲',
        type: 'radioSelect',
        defaultVal: '健在',
        required: true,
        list: OPTIONS.peopleStatus,
        ifOption: {
          key: 'fatherInfo',
          option: [{
            name: {
              label: '父亲姓名',
              type: 'text',
              required: true
            },
            birthTime: {
              label: '父亲出生年月日',
              type: 'text',
              defaultVal: 'XXXX年XX月XX日',
              required: true
            },
            birthPlace: {
              label: '父亲出生地',
              type: 'text',
              required: true
            },
            workPlace: {
              label: '父亲现地址(工作或者生活)',
              tip: '如与您住在一起,请填写“家庭住址”',
              type: 'text',
              required: true
            }
          }]
        }
      },
    

    以上。

    路过的把你们的喜欢留一下啵~💗

    相关文章

      网友评论

          本文标题:日常开发:近100项的巨型表单

          本文链接:https://www.haomeiwen.com/subject/gyleuqtx.html