设计思路

思路: 使用 Element-UI 组件的 tabs 组件循环 ele-form 组件, 形成 group


难点: 既要保证各个 group 之间的独立性, 又要可以使用共用的属性, 例如每个groupform-desc 属性不一样, 但isShowBackBtn都要隐藏, 属于共同属性


解决思路:  groups 数组实现每个 group 的定制, 而如果直接写在 ele-form-group 的属性则是共同属性, 如果即在 ele-form-group 中定义, 又在 group 中定义, 则 group 中属性会覆盖 ele-form-group 中定义的属性


源码: https://github.com/dream2023/vue-ele-form/blob/master/lib/EleFormGroup.vue


示例:


<template>
  <!-- isShowBackBtn 、formBtns 和 @request 将添加在所有 group 的 ele-form 中 -->
  <ele-form-group
    :formBtns="formBtns"
    :groups="groups"
    :isShowBackBtn="false"
    @request="handleSubmit"
    activeGroupId="password"
    submitBtnText="确定"
  ></ele-form-group>
</template>

<script>
  export default {
    name: 'Group',
    data() {
      return {
        // 分组
        groups: [
          {
            // groupId 为分组的 id
            groupId: 'base',
            // groupLabel 为分组的 label
            groupLabel: '基础信息',
            // form 为分组的 ele-form 属性
            form: {
              // 该分组的 ele-form 属性中的 form-desc
              formDesc: {
                name: {
                  type: 'input',
                  label: '姓名'
                },
                age: {
                  type: 'number',
                  label: '年龄'
                }
              },
              formData: {
                name: 'zhang'
              },
              // 会覆盖 ele-form-group 中定义的 submitBtnText
              submitBtnText: '发起'
            },
            // on 为分组的事件
            on: {
              // 会覆盖 ele-form-group中定义的 @request, 实现定制化
              request(data) {
                console.log('点击的第一个', data)
              }
            }
          },
          {
            groupId: 'password',
            groupLabel: '密码',
            form: {
              formDesc: {
                oldPassword: {
                  type: 'password',
                  label: '旧密码'
                },
                newPassword: {
                  type: 'password',
                  label: '新密码'
                },
                confirmPassword: {
                  type: 'password',
                  label: '确认密码'
                }
              },
              formData: {
                oldPassword: '123'
              }
            }
          }
        ],
        formBtns: [
          {
            text: '提交并关闭',
            click() {
              console.log('点我了')
            }
          }
        ]
      }
    },
    methods: {
      handleSubmit(data) {
        console.log(data)
        return Promise.resolve()
      }
    }
  }
</script>


表单项插槽

<ele-form-group
  :formBtns="formBtns"
  :groups="groups"
  :isShowBackBtn="false"
  @request="handleSubmit"
  activeGroupId="password"
  submitBtnText="确定"
>
  // 插槽名称为 groupId + '-' + 表单项key
  // 传递过来的值有 { formData, filed, desc, data  }
  <template v-slot:password-oldPassword="{ formData, filed, desc, data  }">
    <el-input v-model="formData[filed]" />
  </template>
</ele-form-group>

// js部分同上


按钮插槽


<ele-form-group
  :formBtns="formBtns"
  :groups="groups"
  :isShowBackBtn="false"
  @request="handleSubmit"
  activeGroupId="password"
  submitBtnText="确定"
>
  // 插槽名称为 groupId + '-form-btn'
  // 传递过来的值有 { btns  }
  <template v-slot:base-form-btn="{ btns  }">
    <el-button native-type="submit" type="primary">base 提交按钮</el-button>
  </template>
  <template v-slot:password-form-btn="{ btns  }">
    <el-button native-type="submit" type="primary">password 提交按钮</el-button>
  </template>
</ele-form-group>

// js部分同上


Props 属性


props: {
  // 自定义tab属性, 具体参考:https://element.eleme.cn/#/zh-CN/component/tabs#tabs-attributes
  tabAttrs: Object,
  // tab的事件, 具体参考:https://element.eleme.cn/#/zh-CN/component/tabs#tabs-events
  tabOn: Object,
  // 分组
  groups: {
    type: Array,
    required: true
  },
  // 默认激活的tab
  activeGroupId: [String, Number]
}