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
布局。
<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>
插槽
<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[] | [] |
layoutRow | row 属性 | layoutRowProps | {} |
layoutCol | col 属性 | layoutColProps | {} |
modelValue | 绑定值 | Object | {} |
Form Expose
名称 | 说明 |
---|---|
formRef | el-from 的 ref |
Schema 相比 ElFormItem 新增属性
属性名 | 说明 | 类型 | 默认值 |
---|---|---|---|
layout | 布局 | layoutColProps | undefined |
slot | 内容插槽名称 | string | undefined |
labelSlot | label 插槽名称 | string | undefined |
errorSlot | 错误插槽名称 | string | undefined |
component | 组件 | any | undefined |
componentAttrs | 组件属性 | Object | undefined |