具体界面效果是看不到啦,以前的项目,离了后台看不到

html代码
  <div class="form-list" v-if="formTableShow">
    <el-form
      v-for="(item, index) in formList"
      :ref="(el: any) => { setItemRef(el, index)}"
      :model="dataForm['form' + index]"
      :rules="rules['form' + index]"
      :size="formConfigs.size"
      :label-width="formConfigs.labelWidth"
      :inline="formConfigs.inline"
      :label-position="formConfigs.labelPosition"
      :disabled="formConfigs.disabled"
      :status-icon="formConfigs.statusIcon"
    >
      <el-form-item
        :label="foitem.label"
        :prop="foitem.prop"
        :label-width="foitem.labelWdith || 'auto'"
        v-for="foitem in item.forms"
      >
        <el-input v-model="dataForm['form' + index][foitem.prop]"></el-input>
      </el-form-item>
    </el-form>
    <div class="dialog-footer">
      <el-button type="primary" @click="submitRule">保存</el-button>
    </div>
  </div>

PS: 这个分享乃以前项目封装的一个动态表单提取出来的部分,完整的很复杂,功能有以下几点:

  1. 同一个vue文件,展示100多种表格,表格的表头等信息全由接口返回
  2. 所有表格的新增、修改、查看都用同一个弹窗组件,弹窗里面有多种情况(单个表单、多个表单、多个表单和多个表格),其中表格里面也是表单可以编辑且有表单验证,每部分还可能有自己的标题,甚至某些表头或label也有tooltip提示信息
  3. 弹窗内所有表单/表格的所有信息(label、表头、字段、验证…)都由后端配置接口返回,部分复杂的多表单多表格内容因太复杂就由前端自己配置了

鉴于功能及其代码太复杂便不贴出来了

ts部分
<script lang="ts" setup>
import {
  ref,
  reactive,
  computed,
} from 'vue'
import { FormRules } from 'element-plus'
interface FormItem {
  prop: string // 表单字段
  label: string // 表单label
  labelWdith?: string // 表单宽度
  formtype?: string // 表单类型
  defaultValue?: any // 默认值
  rule?: any // 表单验证配置
  config?: any // 表单原生配置
}
// 所有表单配置----这部分是props传入的,提取后稍微改了下
const formList: any = [
  {
    title: 'string',
    forms: [
      {
        //   prop: 'string',              // 字段       必
        //   label: 'string',             // 表单名     必
        //   labelWdith: 'string',        // 表单名宽度 非比 默认:auto
        //   rule: {}                     // 验证规则
        //   ...
      },
      {
        //   prop: 'string',              // 字段       必
        //   label: 'string',             // 表单名     必
        //   labelWdith: 'string',        // 表单名宽度 非比 默认:auto
        //   rule: {}                     // 验证规则
        //   ...
      }
      // ....
    ]
  },
  {
    title: 'string',
    forms: [
      {
        //   prop: 'string',              // 字段       必
        //   label: 'string',             // 表单名     必
        //   labelWdith: 'string',        // 表单名宽度 非比 默认:auto
        //   rule: {}                     // 验证规则
        //   ...
      },
      {
        //   prop: 'string',              // 字段       必
        //   label: 'string',             // 表单名     必
        //   labelWdith: 'string',        // 表单名宽度 非比 默认:auto
        //   rule: {}                     // 验证规则
        //   ...
      }
      // ....
    ]
  }
]
// 表单总体配置
const formConfigs = computed(() => {
  return {
    size: 'default',
    labelWidth: 'auto',
    inline: false,
    labelPosition: 'right',
    disabled: false,
    statusIcon: false,
    ...props.formConfig // 传入的表单公共配置
  }
})
// 所有表单表格配置
const formTableShow = ref(false) 	// 为了解决动态处理验证规则后自动启动验证
const dataForm: any = ref({}) 		// 多套表单字段
const rules: any = reactive({}) 	// 多套验证规则
let resetForm = reactive({}) 		// 为了重置按钮的点击效果
const refList: any = reactive({}) 	// 多个ref
// 初始化表单
const initForm = async () => {
  // 处理多套表单或者表格的dataForm和验证规则
  await formList.map((item: any, index: number) => {
    dataForm.value['form' + index] = {}
    rules['form' + index] = <FormRules>{}
    item.forms?.map((foitem: FormItem) => {
      // 设置表单字段
      dataForm.value['form' + index][foitem.prop] =
        foitem.defaultValue === undefined
          ? foitem.formtype === 'inputnumber'
            ? undefined
            : foitem.formtype === 'picker' &&
              foitem.config?.type?.includes('range')
            ? []
            : ''
          : foitem.defaultValue
      // 设置验证规则
      if (foitem.rule?.message) {
        // 验证规则
        rules['form' + index][foitem.prop] = [
          {
            required:
              foitem.rule.required === undefined ? false : foitem.rule.required,
            message: foitem.rule.message || '请输入',
            trigger: foitem.rule.trigger || 'blur'
          }
        ]
      }
      // 获取字典
      getDict(foitem)
    })
  })
  // 初始化完成再渲染表单表格,负责验证不起效
  formTableShow.value = true
  // 为了重置表单
  resetForm = { ...dataForm.value }
}

// 设置多个ref
const setItemRef = (el: any, index: number) => {
  if (el) {
    refList['ref' + index] = el
  }
}
// 数据提交验证
const formRule = ref(false) // 表单是否通过,和表格相反
const submitRule = async () => {
  await formList.map((item: any, index: number) => {
    refList['ref' + index]?.validate((valid: any, props: any) => {
      if (valid) {
        formRule.value = true
      } else {
        formRule.value = false
      }
    })
  })
  setTimeout(() => {
    // 如果都通过则提交
    if (formRule.value) {
      submitAll()
    }
  }, 100)
}
</script>

当初为了这个功能,掉了不晓得多少头发,趁空闲时间,便记录下来部分

Logo

前往低代码交流专区

更多推荐