formTable组件封装

75 阅读2分钟

formTable组件封装,添加表单验证

代码

<template>
  <div>
    <el-row style="margin-bottom: 20px">
      <el-button type="primary" @click="handleAdd" color="#1F51F1">
        <template #icon>
          <img :src="useAssests('plus.png')" />
        </template>
        新增数据项
      </el-button>
      <el-button :disabled="!tableCheck.length" @click="handleBatchDelete"> 批量删除 </el-button>
    </el-row>
    <el-form :model="form" ref="formRef" :rules="rules">
      <el-table
        height="500"
        @selection-change="(rows) => (tableCheck = rows)"
        :data="form.tableData"
        style="width: 100%"
        cell-class-name="with-form-item"
      >
        <el-table-column type="selection" width="55" />
        <el-table-column label="中文名称" prop="cn_name" width="160">
          <template #default="scope">
            <el-form-item :prop="'tableData.' + scope.$index + '.cn_name'" :rules="rules.cn_name">
              <el-input style="width: 148px" v-model="scope.row.cn_name" placeholder="请输入" clearable />
            </el-form-item>
          </template>
        </el-table-column>
        <el-table-column label="英文名称" prop="en_name" width="160">
          <template #default="scope">
            <el-form-item :prop="'tableData.' + scope.$index + '.en_name'" :rules="rules.en_name">
              <el-input style="width: 148px" v-model="scope.row.en_name" placeholder="请输入" clearable />
            </el-form-item>
          </template>
        </el-table-column>
        <el-table-column label="数据类型" prop="item_type" width="160">
          <template #default="scope">
            <el-form-item :prop="'tableData.' + scope.$index + '.item_type'" :rules="rules.item_type">
              <el-select v-model="scope.row.item_type" placeholder="请选择" style="width: 148px" clearable>
                <el-option
                  :label="item.label"
                  :value="item.value"
                  v-for="(item, index) in item_type_list"
                  :key="index"
                />
              </el-select>
            </el-form-item>
          </template>
        </el-table-column>
        <el-table-column label="数据长度" prop="item_length" width="160">
          <template #default="scope">
            <el-form-item :prop="'tableData.' + scope.$index + '.item_length'" :rules="rules.item_length">
              <el-input
                type="number"
                style="width: 148px"
                v-model.number="scope.row.item_length"
                placeholder="请输入"
                clearable
              />
            </el-form-item>
          </template>
        </el-table-column>
        <el-table-column label="是否可为空" prop="is_let_null" width="160">
          <template #default="scope">
            <el-form-item :prop="'tableData.' + scope.$index + '.is_let_null'" :rules="rules.is_let_null">
              <el-select v-model="scope.row.is_let_null" placeholder="请选择" style="width: 148px" clearable>
                <el-option label="可为空" :value="1" />
                <el-option label="不可为空" :value="0" />
              </el-select>
            </el-form-item>
          </template>
        </el-table-column>
        <el-table-column label="是否主键" prop="is_primary_key" width="160">
          <template #default="scope">
            <el-form-item :prop="'tableData.' + scope.$index + '.is_primary_key'" :rules="rules.is_primary_key">
              <el-select v-model="scope.row.is_primary_key" placeholder="请选择" style="width: 148px" clearable>
                <el-option label="主键" :value="1" />
                <el-option label="非主键" :value="0" />
              </el-select>
            </el-form-item>
          </template>
        </el-table-column>
        <el-table-column label="默认值" prop="default_value" width="160">
          <template #default="scope">
            <el-form-item :prop="'tableData.' + scope.$index + '.default_value'" :rules="rules.default_value">
              <el-input style="width: 148px" v-model="scope.row.default_value" placeholder="请输入" clearable />
            </el-form-item>
          </template>
        </el-table-column>
        <el-table-column label="字段描述" prop="item_msg" width="160">
          <template #default="scope">
            <el-form-item :prop="'tableData.' + scope.$index + '.item_msg'" :rules="rules.item_msg">
              <el-input style="width: 148px" v-model="scope.row.item_msg" placeholder="请输入" clearable />
            </el-form-item>
          </template>
        </el-table-column>

        <el-table-column label="是否为字典项" prop="is_dictionary" width="160">
          <template #default="scope">
            <el-form-item :prop="'tableData.' + scope.$index + '.is_dictionary'" :rules="rules.is_dictionary">
              <el-select v-model="scope.row.is_dictionary" placeholder="请选择" style="width: 148px" clearable>
                <el-option label="主键" :value="1" />
                <el-option label="非主键" :value="0" />
              </el-select>
            </el-form-item>
          </template>
        </el-table-column>

        <el-table-column label="操作" width="120">
          <template #default="{ $index }">
            <el-button type="primary" link @click="delTable($index)"> 删除 </el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-form>
  </div>
</template>

<script lang="ts" setup>
import type { FormInstance } from 'element-plus'
import { item_type_list } from '../../useAddDataResource'
const tableCheck = ref<any[]>([])
const formRef = ref<FormInstance>()
const form = reactive({
  tableData: [] as any,
})

const rules = ref({
  name: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
  age: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
  cn_name: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
  en_name: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
  item_type: [{ required: true, message: '请选择', trigger: 'blur' }],
  item_length: [{ required: true, message: '请输入', trigger: 'blur' }],
  is_let_null: [{ required: true, message: '请选择', trigger: 'blur' }],
  is_primary_key: [{ required: true, message: '请选择', trigger: 'blur' }],
  default_value: [{ required: true, message: '请输入', trigger: 'blur' }],
  item_msg: [{ required: true, message: '请输入', trigger: 'blur' }],
  is_dictionary: [{ required: true, message: '请选择', trigger: 'blur' }],
})
/**验证表单 */
function validForm() {
  return new Promise<{ valid: boolean; data: any[] }>((resolve, reject) => {
    formRef.value!.validate((valid) => {
      resolve({ valid, data: form.tableData })
    })
  })
}

const handleBatchDelete = () => {
  const ids = tableCheck.value.map((i) => i._uuid)
  ids.map((uuid) => {
    const index = form.tableData.findIndex((item) => item._uuid == uuid)
    form.tableData.splice(index, 1)
  })
}
const handleAdd = () => {
  form.tableData.push({
    _uuid: crypto.randomUUID(),
    /**中文名称 */
    cn_name: '',
    /**英文名称 */
    en_name: '',
    /**数据类型 */
    item_type: '',
    /**数据长度 */
    item_length: '',
    /**是否可为空 */
    is_let_null: '',
    /**是否主键 */
    is_primary_key: '',
    /**默认值 */
    default_value: '',
    /**字段描述 */
    item_msg: '',
    /**是否为字典项 */
    is_dictionary: '',
  })
}
//删除
function delTable(i: number) {
  form.tableData.splice(i, 1)
}
defineExpose({
  /**验证表单 */
  validForm,
})
onMounted(() => {})
</script>

<style lang="scss" scoped>
.with-form-item {
  .cell {
    .el-form-item {
      margin: 0;
      :deep(.el-form-item__error) {
        position: static;
      }
    }
  }
}
</style>

效果

image.png