Skip to content
On this page

Form 表单

简介

配置化表单。内部集成 ElLayout 布局,可以快速搭建表单。

基础用法

使用配置schema替换原来模版声明ElFormItem方式,schema是在原有ElFormItem属性基础上添加若干属性。
component添加组件,componentAttrs为组件添加属性

姓名
年龄
学历
备注
值: {}

<template>
  <CxzForm v-model="value" :schema="schema" label-width="80px" />

  <div>值: {{ value }}</div>
</template>

<script setup lang="ts">
import { CxzForm } from 'cxz-ui'
import { ref, markRaw } from 'vue'
import { ElInput, ElInputNumber } from 'element-plus'
import { CxzSelect } from 'cxz-ui'

import type { CxzFormSchema } from 'cxz-ui'

const value = ref({})
const schema = ref<CxzFormSchema[]>([
  {
    prop: 'key_1',
    label: '姓名',
    component: markRaw(ElInput),
    componentAttrs: {
      placeholder: '请输入姓名'
    }
  },
  {
    prop: 'key_2',
    label: '年龄',
    component: markRaw(ElInputNumber)
  },
  {
    prop: 'key_3',
    label: '学历',
    component: markRaw(CxzSelect),
    componentAttrs: {
      placeholder: '请选择学历',
      options: [
        {
          label: '高中',
          value: 0
        },
        {
          label: '大专',
          value: 1
        },
        {
          label: '本科',
          value: 2
        }
      ]
    }
  },
  {
    prop: 'key_4.key_5',
    label: '备注',
    component: markRaw(ElInput),
    componentAttrs: {
      placeholder: '请输入备注',
      type: 'textarea'
    }
  }
])
</script>

布局

layoutRow为表单添加ElRow属性,layoutCol为表单添加ElCol属性。schema中的每项可以添加layout修改公共的layoutCol布局。

label1
label2
label3
label4
label5
label6

<template>
  <CxzForm
    v-model="value"
    :schema="schema"
    label-width="60px"
    label-position="right"
    :layout-row="{ gutter: 20 }"
    :layout-col="{ span: 8 }"
  />
</template>

<script setup lang="ts">
import { CxzForm } from 'cxz-ui'
import { ref, markRaw } from 'vue'
import { ElInput } from 'element-plus'

import type { CxzFormSchema } from 'cxz-ui'

const value = ref({})
const schema = ref<CxzFormSchema[]>([
  {
    prop: 'key_1',
    label: 'label1',
    component: markRaw(ElInput),
    layout: {
      span: 16
    }
  },
  {
    prop: 'key_2',
    label: 'label2',
    component: markRaw(ElInput)
  },
  {
    prop: 'key_3',
    label: 'label3',
    component: markRaw(ElInput)
  },
  {
    prop: 'key_4',
    label: 'label4',
    component: markRaw(ElInput)
  },
  {
    prop: 'key_5',
    label: 'label5',
    component: markRaw(ElInput)
  },
  {
    prop: 'key_6',
    label: 'label6',
    component: markRaw(ElInput),
    layout: {
      span: 24
    }
  }
])
</script>

插槽

label1
修改label2
label3

<template>
  <CxzForm
    v-model="value"
    :schema="schema"
    label-width="100px"
    label-position="right"
  >
    <template #key_2>
      <ElInputNumber v-model="value.key_2" />
    </template>

    <template #key_2_label2>修改label2</template>
  </CxzForm>
</template>

<script setup lang="ts">
import { CxzForm } from 'cxz-ui'
import { ref, markRaw } from 'vue'
import { ElInput, ElInputNumber } from 'element-plus'

import type { CxzFormSchema } from 'cxz-ui'

const value = ref<Record<string, any>>({})

const schema = ref<CxzFormSchema[]>([
  {
    prop: 'key_1',
    label: 'label1',
    component: markRaw(ElInput)
  },
  {
    prop: 'key_2',
    label: 'label2',
    slot: 'key_2',
    labelSlot: 'key_2_label2'
  },
  {
    prop: 'key_3',
    label: 'label3',
    component: markRaw(ElInput)
  }
])
</script>

完整例子

客户姓名
客户手机号
产品名称
产品价格(元)
产品类型
产品描述
产品上架时间
备注

<template>
  <CxzForm
    ref="formRef"
    v-model="value"
    :schema="schema"
    :rules="formRules"
    label-width="120px"
    :layout-row="{ gutter: 20 }"
    :layout-col="{ span: 12 }"
  />

  <div style="padding-left: 120px">
    <el-button type="primary" @click="handleSubmit">提交</el-button>
    <el-button @click="handleReset">重置</el-button>
  </div>
</template>

<script setup lang="ts">
import { CxzForm } from 'cxz-ui'
import { ref, markRaw, reactive } from 'vue'
import { ElInput, ElInputNumber, ElMessage } from 'element-plus'
import { CxzSelect, CxzDatePicker } from 'cxz-ui'

import type { CxzFormSchema } from 'cxz-ui'
import type { FormRules } from 'element-plus'

const value = ref({})
const schema = ref<CxzFormSchema[]>([
  {
    prop: 'customerName',
    label: '客户姓名',
    component: markRaw(ElInput),
    componentAttrs: {
      placeholder: '请输入客户姓名'
    }
  },
  {
    prop: 'customerPhone',
    label: '客户手机号',
    component: markRaw(ElInput),
    componentAttrs: {
      placeholder: '请输入客户手机号'
    }
  },
  {
    prop: 'product.name',
    label: '产品名称',
    component: markRaw(ElInput),
    componentAttrs: {
      placeholder: '请输入产品名称'
    },
    layout: {
      span: 24
    }
  },
  {
    prop: 'product.price',
    label: '产品价格(元)',
    component: markRaw(ElInputNumber)
  },
  {
    prop: 'product.type',
    label: '产品类型',
    component: markRaw(CxzSelect),
    componentAttrs: {
      placeholder: '请选择产品类型',
      options: [
        { label: '水果', value: 0 },
        { label: '服装', value: 1 },
        { label: '家电', value: 2 }
      ]
    }
  },
  {
    prop: 'product.desc',
    label: '产品描述',
    component: markRaw(ElInput),
    componentAttrs: {
      placeholder: '请输入产品描述',
      type: 'textarea'
    },
    layout: {
      span: 24
    }
  },
  {
    prop: 'product.timeRange',
    label: '产品上架时间',
    component: markRaw(CxzDatePicker),
    componentAttrs: {
      placeholder: '请输入备注',
      type: 'daterange',
      startPlaceholder: '开始日期',
      endPlaceholder: '结束日期',
      valueFormat: 'YYYY-MM-DD'
    },
    layout: {
      span: 24
    }
  },
  {
    prop: 'remark',
    label: '备注',
    component: markRaw(ElInput),
    componentAttrs: {
      placeholder: '请输入产品描述',
      type: 'textarea'
    },
    layout: {
      span: 24
    }
  }
])
const formRules = reactive<FormRules>({
  customerName: [
    { required: true, message: '请输入客户姓名', trigger: 'blur' }
  ],
  customerPhone: [
    {
      validator: (rule, value, callback) => {
        if (value && !/^1[3456789]\d{9}$/.test(value)) {
          callback(new Error('请输入正确的手机号'))
        } else {
          callback()
        }
      }
    }
  ],
  'product.name': [
    { required: true, message: '请输入产品名称', trigger: 'blur' }
  ],
  'product.price': [
    { required: true, message: '请输入产品价格', trigger: 'blur' }
  ],
  'product.timeRange': [
    {
      required: true,
      message: '请选择产品上架时间',
      trigger: 'change',
      type: 'array'
    }
  ]
})

const formRef = ref<InstanceType<typeof CxzForm>>()
const handleSubmit = async () => {
  try {
    await formRef.value?.formRef?.validate()
    ElMessage.success('提交成功')
  } catch (error) {
    console.log(error)
  }
}
const handleReset = () => {
  formRef.value?.formRef?.resetFields()
}
</script>

Form 新增属性

属性名说明类型默认值
schema配置CxzFormSchema[][]
layoutRowrow 属性layoutRowProps{}
layoutColcol 属性layoutColProps{}
modelValue绑定值Object{}

Form Expose

名称说明
formRefel-from 的 ref

Schema 相比 ElFormItem 新增属性

属性名说明类型默认值
layout布局layoutColPropsundefined
slot内容插槽名称stringundefined
labelSlotlabel 插槽名称stringundefined
errorSlot错误插槽名称stringundefined
component组件anyundefined
componentAttrs组件属性Objectundefined

Released under the MIT License.