组件库文档 tmui.design
表单 Form
表单包含 输入框, 单选框, 下拉选择, 多选框 等用户输入的组件。 使用表单,您可以收集、验证和提交数据。。
🌶️ 表单 Form 示例
查看模拟效果+
示例模板
vue
<template>
<tm-app ref="app" color="grey-5">
<tm-form @submit="confirm" ref="form" v-model="show" :label-width="190" >
<tm-form-item
desc="你可以点击提交表单来验证"
required
label="身份证号码"
field="nameuser.a"
:rules="[
{ required: true, message: '不能为空', validator: (val) => val.length > 0 },
{ required: true, message: '请输入66', validator: (val) => val == '66' }
]"
>
<!-- 不要问我为什么用v-model.lazy,我很受伤。 -->
<tm-input :inputPadding="[0, 0]" v-model.lazy="show.nameuser.a" :transprent="true" :showBottomBotder="false"> </tm-input>
</tm-form-item>
<tm-form-item required label="选择日期" field="cale" :rules="[{ required: true, message: '请选择日期哦' }]">
<view @click="showCal = !showCal" class="flex flex-row flex-row-center-between">
<tm-text :userInteractionEnabled="false" :label="caleStr || '请选择有效日期'"></tm-text>
<tm-icon :userInteractionEnabled="false" :font-size="24" name="tmicon-angle-right"></tm-icon>
</view>
</tm-form-item>
<tm-form-item
:padding="[0, 0]"
requiredTitleChangeColor
label="选择地区"
field="city"
required
:rules="[{ required: true, message: '请选择地区' }]"
>
<view @click="testClick" class="flex flex-row flex-row-center-between">
<tm-text :userInteractionEnabled="false" :label="show.cityStr || '请选择所在地区地址'"></tm-text>
<tm-icon :userInteractionEnabled="false" :font-size="24" name="tmicon-angle-right"></tm-icon>
</view>
</tm-form-item>
<tm-form-item required label="时间选择" field="time" :rules="[{ required: true, message: '请选择时间+++' }]">
<view @click="showTimePickerView = !showTimePickerView" class="flex flex-row flex-row-center-between">
<tm-text :userInteractionEnabled="false" :label="timeStr || '请选择时间'"></tm-text>
<tm-icon :userInteractionEnabled="false" :font-size="24" name="tmicon-angle-right"></tm-icon>
</view>
</tm-form-item>
<tm-form-item required label="弹出选择" field="pickerStr" :rules="[{ required: true, message: '请选择水果种类' }]">
<view @click="showPicker = !showPicker" class="flex flex-row flex-row-center-between">
<tm-text :userInteractionEnabled="false" :label="show.pickerStr || '请选择水果呀'"></tm-text>
<tm-icon :userInteractionEnabled="false" :font-size="24" name="tmicon-angle-right"></tm-icon>
</view>
</tm-form-item>
<tm-form-item required label="选择水果" field="radio" :rules="[{ required: true, message: '请选择水果' }]">
<tm-radio-group v-model="show.radio">
<tm-radio label="苹果" value="apple"></tm-radio>
<tm-radio label="香焦" value="bonaer"></tm-radio>
</tm-radio-group>
</tm-form-item>
<tm-form-item required label="多选水果种类" field="checkbox" :rules="[{ required: true, message: '请选择' }]">
<tm-checkbox-group v-model="show.checkbox">
<tm-checkbox label="苹果" value="apple"></tm-checkbox>
<tm-checkbox label="香焦" value="bonaer"></tm-checkbox>
<tm-checkbox label="香焦" value="bonaer2"></tm-checkbox>
<tm-checkbox label="香焦" value="bonaer3"></tm-checkbox>
<tm-checkbox label="香焦" value="bonaer4"></tm-checkbox>
</tm-checkbox-group>
</tm-form-item>
<tm-form-item required label="评分" field="rate" :rules="[{ required: true, message: '请选择' }]">
<tm-rate v-model="show.rate" :default-value="show.rate"></tm-rate>
</tm-form-item>
<tm-form-item
required
label="价格选择"
field="slider"
:rules="[{ required: true, message: '请选择', validator: (val) => val.reduce((a, b) => Math.abs(a - b)) !== 0 }]"
>
<tm-slider :width="450" v-model="show.slider" :default-value="show.slider"></tm-slider>
</tm-form-item>
<tm-form-item required label="分割选择" field="segtab" :rules="[{ required: true, message: '请选择' }]">
<tm-segtab :width="420" :list="[{ text: '苹果' }, { text: '香蕉' }]" v-model="show.segtab" :default-value="show.segtab"></tm-segtab>
</tm-form-item>
<tm-form-item label="开关" field="switch" :rules="{ required: true, message: '没有选中哦' }">
<tm-switch v-model="show.switch" :default-value="show.switch" selected="hehe"></tm-switch>
</tm-form-item>
<tm-form-item label="步进值" field="stepper" :rules="{ required: true, message: '没有输入哦' }">
<tm-stepper v-model="show.stepper" :min="1" circular :defaultValue="1"></tm-stepper>
</tm-form-item>
<tm-form-item required label="上传截图" field="upload" :rules="{ required: true, message: '请上传' }">
<tm-upload
:rows="3"
:width="420"
:default-value="show.upload"
url="https://mockapi.eolink.com/tNYKNA7ac71aa90bcbe83c5815871a5b419601e96a5524d/upload"
v-model="show.upload"
></tm-upload>
</tm-form-item>
<tm-form-item :border="false">
<view class="flex flex-row">
<view class="flex-1 mr-32">
<tm-button form-type="submit" label="提交表单" block></tm-button>
</view>
<view class="flex-1">
<tm-button :shadow="0" text form-type="reset" label="重置表单" block></tm-button>
</view>
</view>
</tm-form-item>
</tm-form>
<tm-calendar v-model="show.cale" v-model:show="showCal" :default-value="show.cale"></tm-calendar>
<tm-city-picker v-model="show.city" v-model:model-str="show.cityStr" v-model:show="showCity" :default-value="show.city"></tm-city-picker>
<tm-time-picker
v-model="show.time"
v-model:show="showTimePickerView"
:show-detail="{ year: false, month: false, day: true, hour: true }"
></tm-time-picker>
<tm-picker
:columns="pickerlist"
v-model:model-str="show.pickerStr"
v-model:show="showPicker"
:default-value="show.pickerIndex"
v-model="show.pickerIndex"
></tm-picker>
</tm-app>
</template>
<script lang="ts" setup>
import { ref, nextTick, getCurrentInstance, computed } from 'vue'
import * as dayjs from '@/tmui/tool/dayjs/esm/index'
import tmApp from '@/tmui/components/tm-app/tm-app.vue'
import tmInput from '@/tmui/components/tm-input/tm-input.vue'
import tmSheet from '@/tmui/components/tm-sheet/tm-sheet.vue'
import tmStepper from '@/tmui/components/tm-stepper/tm-stepper.vue'
import tmRadioGroup from '@/tmui/components/tm-radio-group/tm-radio-group.vue'
import tmRadio from '@/tmui/components/tm-radio/tm-radio.vue'
import tmCheckboxGroup from '@/tmui/components/tm-checkbox-group/tm-checkbox-group.vue'
import tmCheckbox from '@/tmui/components/tm-checkbox/tm-checkbox.vue'
import tmRate from '@/tmui/components/tm-rate/tm-rate.vue'
import tmSlider from '@/tmui/components/tm-slider/tm-slider.vue'
import tmSegtab from '@/tmui/components/tm-segtab/tm-segtab.vue'
import tmSwitch from '@/tmui/components/tm-switch/tm-switch.vue'
import tmUpload from '@/tmui/components/tm-upload/tm-upload.vue'
import tmCalendar from '@/tmui/components/tm-calendar/tm-calendar.vue'
import tmCityPicker from '@/tmui/components/tm-city-picker/tm-city-picker.vue'
import tmTimePicker from '@/tmui/components/tm-time-picker/tm-time-picker.vue'
import tmPicker from '@/tmui/components/tm-picker/tm-picker.vue'
import tmImage from '@/tmui/components/tm-image/tm-image.vue'
import tmButton from '@/tmui/components/tm-button/tm-button.vue'
import tmText from '@/tmui/components/tm-text/tm-text.vue'
import tmIcon from '@/tmui/components/tm-icon/tm-icon.vue'
import tmFormItem from '@/tmui/components/tm-form-item/tm-form-item.vue'
import tmForm from '@/tmui/components/tm-form/tm-form.vue'
const app = ref<InstanceType<typeof tmApp> | null>(null)
const form = ref<InstanceType<typeof tmForm> | null>(null)
const DayJs = dayjs.default
const showCal = ref(false)
const showCity = ref(false)
const showTimePickerView = ref(false)
const showPicker = ref(false)
const pickerStr = ref('')
const pickerlist = ref([
{
text: '苹果',
id: 1
},
{
text: '香蕉',
id: 2
},
{
text: '李子',
id: 3
},
{
text: '椰子',
id: 4
}
])
const show = ref({
cale: [],
caleStr: '',
time: '',
radio: '', //bonaer
pickerIndex: [],
pickerStr: '',
checkbox: [],
rate: 0,
slider: [0, 0],
segtab: '',
switch: '',
upload: [],
city: [],
cityStr: '',
nameuser: {
a: ''
},
testff: [],
ha: false,
stepper:1
})
const timeStr = computed(() => (!show.value.time ? '' : DayJs(show.value.time).format('DD日 HH时')))
const caleStr = computed(() => {
if (!show.value.cale || !Array.isArray(show.value.cale)) return ''
if (show.value.cale.length == 0) return ''
return DayJs(show.value.cale[0]).format('YYYY年MM月DD日')
})
const confirm = (e) => {
console.log(e)
}
const testClick = () => {
showCity.value = !showCity.value
}
</script>
🌶️ 兼容性
APP-VUE | APP-NVUE | 小程序 | WEB/H5 | VUE3/TS |
---|---|---|---|---|
✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
🌱 参数
本组件含有公共属性 公共属性
参数名 | 类型 | 默认值 | 描述 |
---|---|---|---|
modelValue | Object | true | 绑定对象值 |
margin | Array<number> | [32,24] | 外间距[x,y]x=左右,y=上下 |
padding | Array<number> | [16,0] | 内间距[x,y]x=左右,y=上下 |
layout | String | horizontal | 表单标签是竖还是横排列:vertical,horizontal。 |
labelWidth | Number | 160 | 如果为0表示自动宽度。 |
labelAlign | String | left | 标签对齐方式 |
border | Boolean | true | 显示下划线。 |
transprent | Boolean | false | 是否透明背景。 |
submit,validate校验后都将得到一致的结果参数从3.1.03开始
🌹 事件
事件名 | 参数 | 返回数据 | 描述 |
---|---|---|---|
submit | - | result | 表单提交函数 |
reset | - | - | 重置表单函数 |
validate | - | result | 执行表单检验,返回验证结果对象,内有isPass属性表示是否验证通过 |
clearValidate | - | - | 清除验证函数 |
update:modelValue | - | - | 更新表单绑定值 |
从3.1.03开始,result结构如下:
ts
{
data: {
...form的modelValue数据
},
// 所有与form-item绑定的filed字段校验的结果数组。
result:{
message:string,//校验后的提示文本
validator: boolean,//是否校验通过
}[],
isPass:boolean //是否校验通过
}
🌽 slot插槽
默认default
🥗 ref方法
validate参数的fileds字段说明 比如你的对象{a:{b:1},d:1},假设你只要校验b字段你应该填写"a.b"
给fileds。即["a.b","d"]
方法名 | 参数 | 返回值 | 描述 |
---|---|---|---|
submit | - | - | 提交表单 |
reset | - | - | 重置表单 |
validate | fileds:string[] = [],type = 'all' | result | type空值时,只校验fileds字段,字段提供时请按照规范填写,手动校验表单,返回验证结果对象,内有isPass属性表示是否验证通过 |
clearValidate | - | - | 清除校验状态 |
pushKey | item:formItem | - | - |
delKey | item:formItem | - | - |
tmFormComnameId | - | - | tmFormId |
🌱 FormItem参数
本组件含有公共属性 公共属性
参数名 | 类型 | 默认值 | 描述 |
---|---|---|---|
parentClass | String | '' | 表单的父类,可以添加自定类名,影响内部 |
align | String | '' | 这个属性主要是用来让左边标题和右边的表单等内容的对齐方式.正常情况用不到.只有在左边和右边内容高度不一致时,比如右边是多行文本或者上传组件,需要上对齐时能用到.此时可以写上flex-row-top-start |
label | String | '' | 显示名称 |
desc | String | '' | 底部表单说明文字 |
margin | Array<number> | [12,12] | 外间距[x,y]x=左右,y=上下 |
padding | <Array<number> | [0,0] | 内间距[x,y]x=左右,y=上下 |
field | String | '' | 如果在forom绑定的model为深层对象,这里的名称需要如下:比如model = {a:2,b:{c:333}},如果想绑定c,则field = "b.c" |
help | String | '' | 表单底部的单项注意说明。 |
required | Boolean | false | 是否显示必填的红色星号* |
rulesv3.0.71+ | Object | Array<rulesItem> | 检验规则,格式见下方 |
border | Boolean | null | 显示下划线。 |
showErrorv3.0.71+ | Boolean | null | 校验不通过的情况下,是否显示错误信息提示 |
requiredTitleChangeColorv3.0.81+ | Boolean | true | 校验不通过时,是否让标题跟着变化文字颜色,默认是。 |
errHeightv3.1.04+ | Number | 30 | 错误空间的高度 |
labelWidthv3.1.07+ | Number | 0 | 标题宽度,如果为0统一使用form上的设置的宽度 |
在3.0.71版本以前rules只支持Object,之后支持Array<rulesItem>。为了向下兼容,之后的版本也是支持非数据校验函数。
rules类型rulesItem 格式如下:
ts
export interface rulesItem {
validator?:Function|boolean,//检验函数。可以是Promise异步回调。
required?:boolean,//是否必填。
message?:string,//检验不合格时的文本
}
🌽 FormItem slot插槽
默认default
插槽:label,表单标题插件 插槽:desc,表单底部的说明文字 插槽:error,表单底部的错误插槽,返回数据 data.message,
ts
v-slot:error = "{data}"
data.message读取错误信息
💏 文档贡献
此页文档由Sunlight贡献,如果对该框架感兴趣的可以参与我们一同进步!