XForm 表单组件
介绍
此表单组件和 Vant
的 Form 组件
不同,XForm
收集了 Vant 的各类表单组件以及自定义组件,目前支持 20种组件,这些组件覆盖了90%日常业务功能;开发者只需要通过简单的配置即可完成日常业务的开发。
引入
这里只展示局部引入使用,如需要全局引入,请参考 全局引入
<template>
<XForm :model="form" :items="formOption" />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { XForm,type XFormItemRow } from 'vant4-kit'
const form = ref()
const formOption=ref<XFormItemRow[]>(
{
type:'input',
name:'name',
label:'姓名',
}
)
</script>
代码演示
基础用法
<template>
<div>
<x-form :model="formValue" :items="formOptions" label-align="top">
<template #customSlot1>
<h3>我是一个自定义 field input插槽</h3>
</template>
<template #customSlot>
<Button type="primary" block>我也是插槽,但我是一个不带field的插槽</Button>
</template>
</x-form>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { Button } from 'vant'
import type { XFormItemOption } from 'vant4-kit';
const formValue = ref({
text: '我是一段自定义文本',
html: '<h4>我是一个带h4标签的html片段</h4>'
})
const formOptions = ref<XFormItemOption>([
{
label: '普通输入',
type: 'input',
name: 'name',
},
{
label: '手机号',
type: 'input',
name: 'tel',
itemProps: {
type: 'tel',
}
},
{
label: '纯数字(可以带小数)',
type: 'input',
name: 'number',
itemProps: {
type: 'number',
}
},
{
label: '整数',
type: 'input',
name: 'digit',
itemProps: {
type: 'digit',
}
},
{
label: '密码输入',
type: 'input',
name: 'password',
itemProps: {
type: 'password',
}
},
{
label: '文本域',
type: 'input',
name: 'textarea',
itemProps: {
type: 'textarea',
row: 2,
autosize: true,
'show-word-limit': true,
maxlength: 50,
}
},
{
label: '步进器',
type: 'stepper',
name: 'age',
},
{
label: '单选',
type: 'radio',
name: 'sex',
options: [
{ text: '男', value: '1' },
{ text: '女', value: '0' },
]
},
{
label: '多选',
type: 'checkbox',
name: 'checkbox',
options: [
{ text: '男', value: '1', attrs: { disabled: true } },
{ text: '女', value: '0' },
{ text: '未知', value: '2' },
],
attrs: {
shape: 'square',
}
},
{
label: '滑动',
type: 'slider',
name: 'slider',
},
{
label: '开关',
type: 'switch',
name: 'switch',
attrs: {
activeValue: '1',
inactiveValue: '0'
}
},
{
type: 'rate',
label: 'rate 评分',
name: 'rate',
attrs: {
count: 6
},
},
{
label: '选择器(多列)',
type: 'picker',
name: 'hubby',
options: [
{
text: '浙江',
value: 'Zhejiang',
children: [
{
text: '杭州',
value: 'Hangzhou',
children: [
{ text: '西湖区', value: 'Xihu' },
{ text: '余杭区', value: 'Yuhang' },
],
},
{
text: '温州',
value: 'Wenzhou',
children: [
{ text: '鹿城区', value: 'Lucheng' },
{ text: '瓯海区', value: 'Ouhai' },
],
},
],
},
{
text: '福建',
value: 'Fujian',
children: [
{
text: '福州',
value: 'Fuzhou',
children: [
{ text: '鼓楼区', value: 'Gulou' },
{ text: '台江区', value: 'Taijiang' },
],
},
{
text: '厦门',
value: 'Xiamen',
children: [
{ text: '思明区', value: 'Siming' },
{ text: '海沧区', value: 'Haicang' },
],
},
],
},
]
},
{
label: '选择器(单列)',
type: 'picker',
name: 'picker1',
options: [
{ text: '杭州', value: 'Hangzhou' },
{ text: '宁波', value: 'Ningbo' },
{ text: '温州', value: 'Wenzhou' },
{ text: '绍兴', value: 'Shaoxing' },
{ text: '湖州', value: 'Huzhou' },
],
},
{
type: 'date-picker',
label: '日期',
name: 'datePicker',
attrs: {
// 'columns-type': ['year']
}
},
{
type: 'date-picker',
label: '日期(年份)',
name: 'datePicker2',
attrs: {
'columns-type': ['year']
},
},
{
type: 'time-picker',
label: '时间选择',
name: 'timePicker',
attrs: {
}
},
{
type: 'datetime-picker',
label: '日期时间(单页)',
name: 'datetimePicker',
attrs: {
showType: 'single',
groupProps: {
'columns-type': ['hour', 'minute']
}
}
},
{
type: 'datetime-picker',
label: '日期时间(组合)',
name: 'datetimePicker1',
attrs: {
showType: 'group',
groupProps: [
{ 'columns-type': ['year', 'month', 'day'] },
{ 'columns-type': ['hour', 'minute', 'second'] }
]
}
},
{
type: 'date-range-picker',
label: '日期范围',
name: 'dateRangePicker',
attrs: {
}
},
{
type: 'time-range-picker',
label: '时间范围',
name: 'timeRangePicker',
attrs: {
}
},
{
type: 'datetime-range-picker',
label: '日期时间范围',
name: 'datetimeRangePicker',
attrs: {
groupProps: [
{ 'columns-type': ['hour', 'minute',] },
{ 'columns-type': ['hour', 'minute', 'second'] }
]
}
},
{
type: 'area',
label: '地区',
name: 'areaPicker',
attrs: {
}
},
{
type: 'cascader',
label: '级联',
name: 'cascader',
attrs: {
useVantAreaData: true
}
},
{
type: 'text',
label: '文本',
name: 'text',
},
{
type: 'html',
label: 'html片段',
name: 'html',
hiddenLabel: false
},
{
type: 'input-slot',
label: '表单插槽',
name: 'customSlot1',
},
{
type: 'slot',
label: '全部插槽',
name: 'customSlot',
},
])
</script>
<style scoped></style>
对其方式
<template>
<x-form :model="formValue" :items="formOptions" :label-align="formValue.labelAlign"
:input-align="formValue.inputAlign">
</x-form>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import type { XFormItemOption } from 'vant4-kit';
const formValue = ref({
labelAlign: 'left',
inputAlign: 'left',
})
const formOptions = ref<XFormItemOption>([
{
label: 'label对其方式',
type: 'radio',
name: 'labelAlign',
options: [
{ text: '左对齐', value: 'left' },
{ text: '右对齐', value: 'right' },
{ text: '顶部对其', value: 'top' },
{ text: '居中对齐', value: 'center' },
]
},
{
label: 'Input对其方式',
type: 'radio',
name: 'inputAlign',
options: [
{ text: '左对齐', value: 'left' },
{ text: '居中对齐', value: 'center' },
{ text: '右对齐', value: 'right' },
]
},
{
label: '普通输入',
type: 'input',
name: 'name',
},
{
label: '手机号',
type: 'input',
name: 'tel',
itemProps: {
type: 'tel',
}
},
{
label: '文本域',
type: 'input',
name: 'textarea',
itemProps: {
type: 'textarea',
row: 2,
autosize: true,
'show-word-limit': true,
maxlength: 50,
}
},
{
label: '步进器',
type: 'stepper',
name: 'age',
},
{
type: 'rate',
label: 'rate 评分',
name: 'rate',
attrs: {
count: 6
},
},
{
type: 'date-picker',
label: '日期',
name: 'datePicker',
attrs: {
}
},
{
type: 'time-picker',
label: '时间选择',
name: 'timePicker',
attrs: {
}
},
{
type: 'date-range-picker',
label: '日期范围',
name: 'dateRangePicker',
attrs: {
}
},
{
type: 'time-range-picker',
label: '时间范围',
name: 'timeRangePicker',
attrs: {
}
},
{
type: 'datetime-range-picker',
label: '日期时间范围',
name: 'datetimeRangePicker',
attrs: {
groupProps: [
{ 'columns-type': ['hour', 'minute',] },
{ 'columns-type': ['hour', 'minute', 'second'] }
]
}
},
])
</script>
<style lang="scss" scoped></style>
校验表单
校验表单有多种配置方式,
- 通过
XForm
的required
参数快捷配置全部表单项必填
<template>
<x-form ref="formRef" :model="formValue" :items="formItems" required >
</x-form>
<div >
<Button type="primary" @click="onSubmit" block>提交</Button>
</div>
</template>
<script lang="ts" setup>
import type {FormInstance,FieldRule} from 'vant'
import { Button,showFailToast } from 'vant'
import type { XFormItemOption } from 'vant4-kit';
import { ref, h } from 'vue'
const formRef=ref<FormInstance>()
const formValue = ref({})
const formItems = ref<XFormItemOption>([
{
type: 'input',
label: '账号',
name:'name'
},
{
type: 'input',
label: '密码',
name:'pasword',
attrs:{
type:'password',
}
},
])
const onSubmit=()=>{
formRef.value?.validate().then(()=>{
console.log('submit values =',formValue.value);
}).catch(error=>{
console.log('error',error);
showFailToast('请检查表单填写')
})
}
</script>
<style lang="scss" scoped>
</style>
- 通过在
XForm
的rules
参数来配置表单项的自定义校验
<template>
<x-form ref="formRef" :model="formValue" :items="formItems" :rules="formRules" >
</x-form>
<div >
<Button type="primary" @click="onSubmit" block>提交</Button>
</div>
</template>
<script lang="ts" setup>
import type {FormInstance,FieldRule} from 'vant'
import { Button,showFailToast } from 'vant'
import type { XFormItemOption } from 'vant4-kit';
import { ref, h } from 'vue'
const formRef=ref<FormInstance>()
const formValue = ref({})
const formItems = ref<XFormItemOption>([
{
type: 'input',
label: '姓名',
name:'name'
},
{
type: 'input',
label: '手机号',
name:'tel',
attrs:{
type:'tel',
}
},
{
type: 'input',
label: '邮箱',
name:'email',
},
])
const formRules:{ [key:string]:FieldRule[] }={
name:[
{ required:true,message:'请输入姓名',trigger:['onBlur']}
],
tel:[
{ required:true,message:'请输入手机号',trigger:['onBlur']},
{ pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号', trigger: ['onChange','onBlur'] },
],
email:[
{ required:true,message:'请输入邮箱',trigger:['onBlur',]},
{ pattern: /^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/, message: '请输入正确的邮箱', trigger: ['onChange','onBlur'] },
]
}
const onSubmit=()=>{
formRef.value?.validate().then(()=>{
console.log('submit values =',formValue.value);
}).catch(error=>{
console.log('error',error);
showFailToast('请检查表单填写')
})
}
</script>
<style lang="scss" scoped>
</style>
- 通过在
XForm
组件的items
的参数配置对象中配置required
,实现当前表单的必填校验,或在参数中配置rules
来实现当前表单项的自定义校验规则
<template>
<x-form ref="formRef" :model="formValue" :items="formItems"></x-form>
<div>
<Button type="primary" @click="onSubmit" block>提交</Button>
</div>
</template>
<script lang="ts" setup>
import type { FormInstance, FieldRule } from 'vant'
import { Button, showFailToast } from 'vant'
import type { XFormItemOption } from 'vant4-kit';
import { ref, h } from 'vue'
const formRef = ref<FormInstance>()
const formValue = ref({})
const formItems = ref<XFormItemOption>([
{
type: 'input',
label: '姓名',
name: 'name',
required: true,
},
{
type: 'input',
label: '邮箱',
required: true,
name: 'email',
itemProps: {
rules: [
{ pattern: /^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/, message: '请输入正确的邮箱', trigger: ['onChange', 'onBlur'] },
],
}
},
{
type: 'checkbox',
label: '兴趣',
name: 'hobby',
required: true,
options: [
{ text: '篮球', value: 'basketball' },
{ text: '足球', value: 'football' },
{ text: '羽毛球', value: 'badminton' },
],
attrs: {
shape: 'square'
}
}
])
const onSubmit = () => {
formRef.value?.validate().then(() => {
console.log('submit values =', formValue.value);
}).catch(error => {
console.log('error', error);
showFailToast('请检查表单填写')
})
}
</script>
<style lang="scss" scoped></style>
插槽用法
插槽用法分为两种,一种是在 XForm
组件上直接使用插槽,另外一种是直接在itemProps
通过配置 slots 属性下的插槽渲染函数来实现自定义渲染
组件插槽方式
<template>
<x-form :model="formValue" :items="formItems">
<template #labelSlot.label>
<span style="color:red">我是label插槽</span>
</template>
<template #leftIconSlot.left-icon>
<Icon name="smile" />
</template>
<template #rightIconSlot.right-icon>
<Icon name="fire-o" color="#ee0a24" />
</template>
<template #errorMessage.error-message="{ message }">
<span>错误提示插槽:{{ message }}</span>
</template>
<template #button.button>
<Button type="primary" size="small">尾部按钮</Button>
</template>
<template #extra.extra>
<span>额外内容</span>
</template>
<template #customSlot>
<h3>自定义表单项输入区插槽</h3>
</template>
<template #solt>
<h3>自定义表单项插槽</h3>
</template>
</x-form>
</template>
<script lang="ts" setup>
import type { XFormItemOption } from 'vant4-kit';
import { ref } from 'vue'
import { Icon, Button } from 'vant';
const formValue = ref({})
const formItems = ref<XFormItemOption>([
{
type: 'input',
label: 'Label 插槽',
name: 'labelSlot'
},
{
type: 'input',
label: '左图标插槽',
name: 'leftIconSlot'
},
{
type: 'input',
label: '有图标插槽',
name: 'rightIconSlot'
},
{
type: 'input',
label: '按钮插槽',
name: 'button'
},
{
type: 'input',
label: '错误提示插槽',
name: 'errorMessage',
itemProps: {
'errorMessage': '我错啦'
}
},
{
type: 'input',
label: '额外内容插槽',
name: 'extra'
},
{
type: 'input-slot',
label: '自定义插槽',
name: 'customSlot'
},
{
type: 'slot',
label: '输入框',
name: 'solt'
}
])
</script>
<style lang="scss" scoped></style>
插槽函数
<template>
<x-form :model="formValue" :items="formItems">
</x-form>
</template>
<script lang="ts" setup>
import type { XFormItemOption } from 'vant4-kit';
import { ref, h } from 'vue'
import { Icon, Button } from 'vant';
const formValue = ref({})
const formItems = ref<XFormItemOption>([
{
type: 'input',
label: 'Label 插槽',
name: 'labelSlot',
itemProps: {
slots: {
label: () => h('span', { style: { color: 'red' } }, '我是label插槽')
}
}
},
{
type: 'input',
label: '图标插槽',
name: 'leftIconSlot',
itemProps: {
slots: {
'left-icon': () => h(Icon, { name: 'smile' }),
'right-icon': () => h(Icon, { name: 'fire-o', color: '#ee0a24' })
}
}
},
{
type: 'input',
label: '按钮插槽',
name: 'button',
itemProps: {
slots: {
'button': () => h(Button, { type: 'primary', size: 'small' }, '尾部按钮'),
}
}
},
{
type: 'input',
label: '错误提示插槽',
name: 'errorMessage',
itemProps: {
'errorMessage': '我错啦',
slots: {
'error-message': ({ message }: { message: string }) => h('span', { style: { color: 'red' } }, `错误提示插槽:${message}`)
}
}
},
{
type: 'input',
label: '额外内容插槽',
name: 'extra',
itemProps: {
slots: {
extra: () => h('span', { style: { color: 'green' } }, `额外内容`)
}
}
},
{
type: 'input-slot',
label: '自定义插槽',
name: 'customSlot',
itemProps: {
slots: {
input: () => h('div', {}, '自定义插槽'),
}
}
},
])
</script>
<style lang="scss" scoped></style>
只读表单
<template>
<x-form :model="formValue" :items="formOptions" readonly>
</x-form>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import type { XFormItemOption } from 'vant4-kit';
const formValue = ref({
name: '苏苏',
tel: '123456789',
idCard: '320830200012120124',
textarea: '测试数据',
password: '15212344567',
checkbox: ['2'],
slider: 20,
rate: 3,
switch: '1',
picker1Text: '温州',
picker1: 'Wenzhou'
})
const formOptions = ref<XFormItemOption>([
{
label: '普通输入',
type: 'input',
name: 'name',
},
{
label: '身份证号',
type: 'input',
name: 'idCard',
itemProps: {
formatter: (val) => {
console.log('val', val);
return val.replace(/(\d{3})\d*(\d{4})/, '$1' + '*'.repeat(val.length - 7) + '$2');
}
}
},
{
label: '手机号',
type: 'input',
name: 'tel',
itemProps: {
type: 'tel',
formatter: (val) => {
const phoneNumber = val.toString().replace(/\D/g, '');
return phoneNumber.replace(/(\d{3})\d*(\d{4})/, '$1' + '*'.repeat(phoneNumber.length - 7) + '$2');
}
}
},
{
label: '密码输入',
type: 'input',
name: 'password',
itemProps: {
type: 'password',
}
},
{
label: '文本域',
type: 'input',
name: 'textarea',
itemProps: {
type: 'textarea',
row: 2,
autosize: true,
'show-word-limit': true,
maxlength: 50,
}
},
{
label: '步进器',
type: 'stepper',
name: 'age',
},
{
label: '单选',
type: 'radio',
name: 'sex',
options: [
{ text: '男', value: '1' },
{ text: '女', value: '0' },
]
},
{
label: '多选',
type: 'checkbox',
name: 'checkbox',
options: [
{ text: '男', value: '1', attrs: { disabled: true } },
{ text: '女', value: '0' },
{ text: '未知', value: '2' },
],
attrs: {
shape: 'square',
}
},
{
label: '滑动',
type: 'slider',
name: 'slider',
},
{
label: '开关',
type: 'switch',
name: 'switch',
attrs: {
activeValue: '1',
inactiveValue: '0'
}
},
{
type: 'rate',
label: 'rate 评分',
name: 'rate',
attrs: {
count: 6
},
},
{
label: '选择器',
type: 'picker',
name: 'picker1',
options: [
{ text: '杭州', value: 'Hangzhou' },
{ text: '宁波', value: 'Ningbo' },
{ text: '温州', value: 'Wenzhou' },
{ text: '绍兴', value: 'Shaoxing' },
{ text: '湖州', value: 'Huzhou' },
],
},
{
type: 'date-picker',
label: '日期',
name: 'datePicker',
attrs: {
// 'columns-type': ['year']
}
},
{
type: 'date-picker',
label: '日期(年份)',
name: 'datePicker2',
attrs: {
'columns-type': ['year']
},
},
{
type: 'time-picker',
label: '时间选择',
name: 'timePicker',
attrs: {
}
},
{
type: 'date-range-picker',
label: '日期范围',
name: 'dateRangePicker',
attrs: {
}
},
{
type: 'time-range-picker',
label: '时间范围',
name: 'timeRangePicker',
attrs: {
}
},
{
type: 'datetime-range-picker',
label: '日期时间范围',
name: 'datetimeRangePicker',
attrs: {
groupProps: [
{ 'columns-type': ['hour', 'minute',] },
{ 'columns-type': ['hour', 'minute', 'second'] }
]
}
},
])
</script>
<style lang="scss" scoped></style>
Api
Props 参数
XForm
组件支持 Vant
的 Form
组件的所有属性,具体属性请参考 Vant Form,以下是 XForm
组件特有的属性
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
model | 搜集表单组件产生的值 | object | {} |
items | 表单组件渲染配置,参见:items的表单项配置对象 | XFormItemRow[] | [] |
rules | 设置表单组件的检验规则 | object | {} |
inset | 是否展示为圆角卡片风格 | boolean | true |
items的表单项配置对象
参数 | 说明 | 类型 | 是否必填 |
---|---|---|---|
type | 需要渲染的组件类型,参见:支持的组件类型 | CompType | ✅️ |
prop | 表单项标识key | string | ✅️ |
label | 表单项名称 | string | ❌️ |
required | 是否显示表单必填星号 | boolean | ❌️ |
rules | 表单校验规则 | Record<string,FieldRule[]> | ❌️ |
itemProps | 表单项目配置props(即:Field参数) | object | ❌️ |
attrs | type 对应原始组件的属性及方法,针对个别组件的辅助增强特性参见下文的attrs 辅助特性 | object | ❌️ |
options | 选择类组件的选择项 | PickerOption[] | ❌️ |
vif | 是否显示当前表单项,默认true | boolean | ((values: Record<string,any>) => boolean); | ❌️ |
hiddenLabel | 是否隐藏label内容区域 | boolean | ❌️ |
attrs 辅助特性
✨ 辅助特性 1️⃣ (cascader )
当 type: 'cascader'
时,可以配置 attrs下的 useVantAreaData
为 true
来使用Vant提供的全国区域选择数据,或者自定义 options
...,
{
type:'cascader',
label:'地区选择',
name:'area',
attrs:{
useVantAreaData: true
}
}
...
✨ 辅助特性 2️⃣(datetime-picker)
当 type: 'datetime-picker'
时,可以通过在 attrs
中配置 showType
来选择选择器类型是单页形式
还是分组形式
。
showType
可选值有 single
、group
,默认为 group
// showType=single 时,
// groupProps参数配置参考: /md/components/datetime-picker/#props-参数
{
type:'datetime-picker',
label:'日期时间',
name:'datetime',
attrs:{
showType: 'single',
groupProps: {}
}
}
// or
// showType=group 时
// groupProps[0]的参数配置参考:https://vant.pro/vant/#/zh-CN/date-picker#props
// groupProps[1]的参数配置参考:https://vant.pro/vant/#/zh-CN/time-picker#props
{
type:'datetime-picker',
label:'日期时间',
name:'datetime',
attrs:{
showType: 'group',
groupProps: [
{},
{}
]
}
}
✨ 辅助特性 3️⃣(范围选择器 )
配置的组件类型为如下三种时,对应的attrs
均存在 groupProps
数组。
date-range-picker
groupProps[0]
参考:Vant DatePicker
groupProps[1]
参考:Vant DatePicker
time-range-picker
groupProps[0]
参考:Vant TimePicker
groupProps[1]
参考:Vant TimePicker
datetime-range-picker
groupProps[0]
参考:DateTimePicker
groupProps[1]
参考:DateTimePicker
Events 事件
除submit
、failed
两种事件外,其他事件在触发时才返回的参数中,第一个参数 prop
为触发此事件的组件唯一标识
事件名 | 说明 | 回调参数 |
---|---|---|
submit | 提交表单且验证通过后触发 | values: object |
failed | 提交表单且验证不通过后触发 | errorInfo: { values: object, errors: object[] } |
change | 具备change 事件的组件选项改变时触发 | prop:string,args:any |
child-change | options 中需具备change 事件选择项在选项改变时触发,如果checkbox | prop:string,args:any |
blur | 具备blur 事件的组件,输入框失去焦点时触发 | prop:string,event: Event |
focus | 具备focus 事件的组件,输入框获得焦点时触发 | prop:string,event: Event |
click | 具备click 事件的组件,点击组件时触发 | prop:string,event: Event |
child-click | options 中需具备click 事件的选项在点击时触发,如果radio ,checkbox ,点击组件时触发 | prop:string,args:any |
confirm | 点击弹框完成按钮时触发 | prop:string,{ selectedValues, selectedOptions, selectedIndexes } |
cancel | 点击弹框取消按钮时触发 | prop:string,{ selectedValues, selectedOptions, selectedIndexes } |
drag-start | slider 类型组件,开始拖动时触发 | prop:string,event: TouchEvent |
drag-end | slider 类型组件,结束拖动时触发 | prop:string,event: TouchEvent |
plus | stepper 类型组件,点击增加按钮时触发 | prop:string |
minus | stepper 类型组件,点击减少按钮时触发 | prop:string |
overlimit | stepper 类型组件,点击不可用的按钮时触发 | prop:string |
finish | cascader 类型组件,全部选项选择完成后触发 | prop:string,{ value: Numeric, selectedOptions: CascaderOption[], tabIndex: number } |
click-tab | cascader 类型组件,点击标签时触发 | prop:string,tabIndex: number, title: string |
Slots 插槽
针对片options
配置的参数 prop对应的value值为唯一属性来自定义对应部分Field
组件的插槽内容
名称 | 说明 | 参数 |
---|---|---|
[prop值] | 自定义type='input-slot' ,prop=[prop值] 的Field输入框位置渲染内容 或 自定义 type='slot' ,prop=[prop值] 渲染内容 | - |
[prop值] .label | 自定义标识为prop 的输入框左侧文本 | - |
[prop值] .left-icon | 自定义标识为prop 的输入框头部图标 | - |
[prop值] .right-icon | 自定义标识为prop 的输入框尾部图标 | - |
[prop值] .button | 自定义标识为prop 的输入框尾部按钮 | - |
[prop值] .error-message | 自定义标识为prop 的组件底部错误提示文案 | { message: string } |
[prop值] .extra | 自定义标识为prop 的输入框最右侧的额外内容 | - |
Expose 实例方法
通过 ref 可以获取到 XForm
实例并调用实例方法。XForm
支持Vant Form所有的实例化方法
支持的组件类型
组件类型 | 对应Vant 组件 | 说明 |
---|---|---|
input | Field 输入框 | |
picker | Picker 选择器 | |
cascader | Cascader 级联选择 | |
area | Area 省市区选择 | |
radio | Radio 单选框 | |
checkbox | Checkbox 复选框 | |
date-picker | DatePicker 日期选择 | |
time-picker | TimePicker 时间选择 | |
datetime-picker | - | 新定义组合类组件 |
date-range-picker | - | 新定义组合类组件 |
time-range-picker | - | 新定义组合类组件 |
datetime-range-picker | - | 新定义组件 |
switch | Switch 开关 | |
rate | Rate 评分 | |
slider | Slider 滑块 | |
stepper | Stepper 步进器 | |
text | - | 渲染普通文本 |
html | - | 渲染html片段 |
input-slot | - | 自定义Field input插槽 |
slot | - | 自定义form-item |
XForm类型定义
类型申明
type SelectComp = 'picker' | 'cascader' | 'area' | 'radio' | 'checkbox';
type InputComp = 'input';
type DateComp = 'date-picker' | 'time-picker' | 'datetime-picker' | 'date-range-picker' | 'time-range-picker' | 'datetime-range-picker';
type OtherComp = 'switch' | 'rate' | 'slider' | 'stepper' | 'text' | 'html' | 'slot' | 'input-slot';
export type CompTypes = SelectComp | InputComp | DateComp | OtherComp;
export type XFormItemRow<T extends CompTypes = CompTypes> = {
type: T;
label?: string;
name: string;
required?: boolean;
attrs?: (T extends keyof CompAttrsPropsMap ? (CompAttrsPropsMap[T] & Indexable) : Indexable) & { slots?: { [k: string]: (...args: any) => any } };
vif?: boolean | ((values: Indexable) => boolean);
rules?: FieldRule[];
itemProps?: Partial<FieldProps> & { slots?: XFormItemSlots<T> } & Indexable;
hiddenLabel?: boolean;
popup?: PopupProps
} & OptionsRow<T>
export type PickerOption<T> = {
text: string;
value: Numeric;
children?: PickerOption<T>[];
} & T extends 'radio' | 'checkbox' ? {
attrs: T extends 'radio' ? RadioProps : CheckboxProps;
} : Indexable;
export type OptionsRow<T> = T extends SelectComp ? {
options: PickerOption<T>[];
} : {
options?: PickerOption<T>[];
};