表单子组件 xFormItem
预览
介绍
从1.1.2开始允许非xform直接子节点了,也就是在xform可以嵌套view进行form-item布局了,但建议不要嵌套太深,影响性能. 1.1.17开始支持嵌套对象字段,key必须/分割如'user/id',sdk不支持以.分割符。
平台兼容
| Harmony | H5 | andriod | IOS | 小程序 | UTS | UNIAPP-X SDK | version |
|---|---|---|---|---|---|---|---|
| ☑ | ☑ | ☑️ | ☑️ | ☑️ | ☑️ | 4.76+ | 1.1.18 |
文件路径
ts
@/uni_modules/tmx-ui/components/x-form-item/x-form-item.uvue使用
ts
<x-form-item></x-form-item>Props 属性
| 名称 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| label | 表单名称 | string | "" |
| showLabel | 是否显示标题 | boolean | true |
| field | 校验的字段名称,字段名称一定要存在于form表单数据中。否则报错。 | string | "" |
| required | 是否是必填项。设置了此值,才会执行校验。 | boolean | false |
| showRequired | 是否显示校验必填项前面的红*符号 | boolean | true |
| rule | 校验规则对象 | Array | () : FORM_RULE[] => [] as FORM_RULE[] |
| labelWidth | 标签宽(横向表单时有效),默认空值取父form统一的设置。 | string | "" |
| labelDirection | 默认空值取父form统一的设置。vertical\horizontal | string | "" |
| labelFontColor | 默认空值取父form统一的设置。标签的文本颜色 | string | "" |
| labelFontSize | 默认空值取父form统一的设置。标签的文本大小 | string | "" |
| labelAlign | 标签标题对齐方式 left,right,center | string | "left" |
| showBottomBorder | 是否显示底部边框 | boolean | true |
| cellPadding | 排版布局上和下的间隙。[上,下] | Array | () : string[] => ['10', '10'] as string[] |
| labelPadding | 排版布局上和下的间隙。[上,下],竖向时才生效 | Array | () : string[] => ['12', '12'] as string[] |
| showError | 校验时,是否显示下边的出错信息 | boolean | true |
| contentStyle | 默认区域内的自定样式 | string | "" |
Events 事件
| 名称 | 参数 | 说明 |
|---|
Slots 插槽
| 名称 | 说明 | 数据 |
|---|---|---|
| label | 标题 | - |
| default | 默认内容区域 | - |
| error | 出错提示的插槽 | - |
Ref 方法
| 名称 | 参数 | 返回值 | 说明 |
|---|---|---|---|
| vaildCompele | - | - | - |
| getVaildStatus | - | - | - |
| clearValid | - | - | - |
示例文件路径
json
/pages/biaodan/form示例源码
uvue
vue
<template>
<!-- #ifdef MP-WEIXIN -->
<page-meta :page-style="`background-color:${xThemeConfigBgColor}`">
<navigation-bar :background-color="xThemeConfigNavBgColor"
:front-color="xThemeConfigNavFontColor"></navigation-bar>
</page-meta>
<!-- #endif -->
<x-sheet>
<x-text font-size="18" class=" text-weight-b mb-8">表单 xForm</x-text>
<x-text color="#999999">与官方不同的是,它只为数据进行验证,因此不仅仅局限表单组件。而是任意数据进行的验证收集,比官方更灵活,与web组件对齐的校验。</x-text>
<x-text color="#999999">为了体验提供了属性:默认如果有字段校验不过,会把页面滚动到当前出错 的位置。</x-text>
<x-text color="#999999">1.1.17开始支持嵌套对象字段,key必须/分割如'user/id'</x-text>
</x-sheet>
<x-sheet>
<x-form ref="form" :rules="rules" @submit="(submitData as resultTtype)"
v-model="(reqData as USER_TYPE)">
<x-form-item field="username" label="联系姓名" :required="true">
<x-input cursor-color="red" color='transparent' v-model="(reqData.username as string)"
align="right"></x-input>
</x-form-item>
<x-form-item field="testChildrenForm/text" label="嵌套字段" :required="true">
<x-input cursor-color="red" color='transparent' v-model="(reqData.testChildrenForm.text as string)"
align="right"></x-input>
</x-form-item>
<x-form-item v-if="reqData.testFiled!=null" field="testFiled" label="测试可空字段" :required="true">
<x-input cursor-color="red" color='transparent' v-model="(reqData.testFiled as string|null)"
align="right"></x-input>
</x-form-item>
<x-form-item field="title" label="产品标题" :required="true">
<x-input color='transparent' v-model="(reqData.title as string)" align="right"></x-input>
</x-form-item>
<x-form-item field="price" label="产品价格" :required="true">
<x-input color='transparent' type="number" v-model="(reqData.price as string)" right-text="万元"
align="right"></x-input>
</x-form-item>
<x-form-item :show-bottom-boder="false" field="num" label="库存数量" :required="true">
<view class="flex flex-row flex-row-center-end">
<x-stepper width="120" v-model="(reqData.num as number)"></x-stepper>
</view>
</x-form-item>
<x-form-item label="上传图片" field="upload" :required="true" contentStyle="display:flex;flex-direction:row;justify-content:flex-end">
<x-upload-media :max-count="3" align="right" v-model="(reqData.upload as XUPLOADFILE_FILE_VALUE[])" :column="3"
style="width: 200px;" img-height="70px"></x-upload-media>
</x-form-item>
<x-form-item field="radio" label="选择性别" :required="true">
<x-radio-group v-model="(reqData.radio as string)" class="flex flex-row flex-row-center-end">
<x-radio class="mr-20" value="男" label="男"></x-radio>
<x-radio value="女" label="女"></x-radio>
</x-radio-group>
</x-form-item>
<x-form-item field="checkbox" label="选择水果" :required="true">
<x-checkbox-group v-model="(reqData.checkbox as string[])"
class="flex flex-row flex-row-center-end">
<x-checkbox v-for="(item,index) in ['苹果','香蕉','梨子','地龙']" :key="index" class="ml-20 mb-10"
:value="item" :label="item"></x-checkbox>
</x-checkbox-group>
</x-form-item>
<x-button form-type="form" class="mt-32" :block="true">保存资料</x-button>
<x-text font-size="12" color="error"
class="text-align-center pt-24">表单收集与组件不是绑定结构只与form-item绑定,因此不会像官方那样局限,可以作为一个数据验证器来理解。</x-text>
</x-form>
</x-sheet>
<x-sheet>
<x-text font-size="18" class=" text-weight-b mb-8">ref方法对上述表单验证</x-text>
<view class="flex flex-row ">
<x-button class="flex-1 mr-n6" @click="submitByClick">ref验证</x-button>
<x-button class="flex-1 mr-n6" @click="clearValid">清除验证</x-button>
<x-button class="flex-1" @click="submitref">只验证用户名</x-button>
</view>
</x-sheet>
<x-sheet>
<x-text font-size="18" class=" text-weight-b mb-8">风格可以自己随意变化</x-text>
<x-text color="#999999">下面开启watchValidStatus并绑定v-model:modelValid实时管理提交按钮校验状态。</x-text>
</x-sheet>
<x-sheet>
<x-form v-model:modelValid="(isPass as boolean)" :watchValidStatus="true" @submit="(submit as resultTtype)" v-model="(logindata as LOGIN_TYPE)"
:label-direction="('vertical' as labelDirType)">
<x-form-item :cell-padding="['0','0']" :showBottomBorder="false" :rule="rules.get('username')!" field="user"
label="用户帐号" :required="true">
<x-input darkBgColor="" left-icon="account-pin-circle-fill" placeholder="请输入你的帐号"
v-model="(logindata.user as string)"></x-input>
</x-form-item>
<x-form-item :cell-padding="['0','0']" :showBottomBorder="false" :rule="rules.get('password')!" field="pass"
label="登录密码" :required="true">
<x-input darkBgColor="" :password="true" left-icon="lock-password-fill" placeholder="请输入8位密码"
v-model="(logindata.pass as string)"></x-input>
</x-form-item>
<x-button form-type="form" :disabled="!isPass" class="mt-32" icon="lock-unlock-fill" :block="true">登入</x-button>
</x-form>
</x-sheet>
<view style="height: 550px;"></view>
</template>
<script lang="ts" setup>
import { ref } from "vue"
import type { FORM_RULE,FORM_SUBMIT_RESULT, XUPLOADFILE_FILE_VALUE } from "@/uni_modules/tmx-ui"
// @ts-ignore
const form = ref<XFormComponentPublicInstance | null>(null)
type resultTtype = (evt : FORM_SUBMIT_RESULT) => void;
type labelDirType = 'vertical' | 'horizontal'
type USER_TYPE_CHILDRENFORM = {
text:string
}
type USER_TYPE = {
username : string;
password : string;
title : string;
price : string;
num : number;
testFiled ?: string,
radio : string,
checkbox : string[],
testChildrenForm:USER_TYPE_CHILDRENFORM,
upload : XUPLOADFILE_FILE_VALUE[]
};
type LOGIN_TYPE = {
user : string,
pass : string
}
const isPass = ref(false)
// RULES可以集中管理,也可以单位分开管理。到form-item rule上或者form中的rules上
let rules = new Map<string, FORM_RULE[]>([
["username", [
{
type: "string",
errorMessage: "姓名填写不正确,不能空,且要小于4个字符",
trigger: 'blur',
valid: (val : any | null) : boolean => {
let pval = val as string;
return pval.length > 0 && pval.length <= 4
}
}
]],
["testChildrenForm/text", [
{
type: "string",
errorMessage: "嵌套字段不能空,且要小于4个字符",
trigger: 'blur',
valid: (val : any | null) : boolean => {
let pval = val as string;
return pval.length > 0 && pval.length <= 4
}
}
]],
["password", [
{
type: "number",
errorMessage: "请输入8位密码",
valid: (val : any | null) : boolean => {
let pval = val as string;
return pval.length == 8
}
}
]],
["title",[
{
type: "string",
errorMessage: "产品标题不空,且大于5个字符小于12个字符",
valid: (val : any | null) : boolean => {
let pval = val as string;
return pval.length > 5 && pval.length <= 12
}
}
]],
["price",[
{
type: "number",
errorMessage: "价格不能小于30元",
min: 30
}
]],
["num",[
{
type: "number",
errorMessage: "商品库存在2-200之间",
min: 2,
max: 100
}
]],
["upload",[
{
type: "array",
errorMessage: "请最少选择1张图片最多3张",
min: 1,
max: 3
} as FORM_RULE
]]
])
const reqData = ref<USER_TYPE>({
username: "",
password: "",
title: "",
price: "",
num: 0,
radio: "",
checkbox: [] as string[],
testChildrenForm:{
text:""
},
upload: [] as XUPLOADFILE_FILE_VALUE[]
})
const logindata = ref<LOGIN_TYPE>({
user: "",
pass: ""
})
const submitData = (evt : FORM_SUBMIT_RESULT) => {
console.log(evt)
if (!evt.valid) {
uni.showToast({ title: evt.errorMessage, icon: 'none' })
return;
}
}
const submit = (evt : FORM_SUBMIT_RESULT) => {
if (!evt.valid) {
uni.showToast({ title: evt.errorMessage, icon: 'none' })
return;
}
console.log(evt)
}
// 只验证username
const submitref = () => {
form.value!.valid(['username'] as string[])
}
//验证全部
const submitByClick = () => {
let result = form.value!.valid([] as string[]) as FORM_SUBMIT_RESULT
// console.log(result)
}
const clearValid = () => {
form.value!.clearValid()
}
</script>
<style lang="scss">
</style>