Form
组件类型:UxFormComponentPublicInstance
支持任何组件,只作为数据校验
平台兼容性
UniApp X
Android | iOS | web | 鸿蒙 Next | 小程序 |
---|---|---|---|---|
√ | √ | √ | x | √ |
UniApp Vue Nvue
Android | iOS | web | 鸿蒙 Next | 小程序 |
---|---|---|---|---|
x | x | √ | x | x |
Props
属性名 | 类型 | 默认值 | 说明 |
---|---|---|---|
direction | String | horizontal | 布局方向 |
width | Any | 自适应 | 宽度 |
size | Any | $ux.Conf.fontSize | 字体大小 |
errorSize | Any | 11 | 错误提示字体大小 |
color | String | $ux.Conf.fontColor | 字体颜色 |
darkColor | String | 深色none-不显示,auto-自动适配深色模式,其他-颜色 |
direction
值 | 说明 |
---|---|
horizontal水平 | |
vertical垂直 |
Events
事件名 | 说明 | 参数 |
---|---|---|
submit | 提交数据时触发 |
示例代码
html
<template>
<ux-page :stack="showDoc">
<ux-navbar :title="title" :bold="true">
<template v-slot:right>
<!-- #ifndef MP -->
<ux-button theme="text" icon="/static/tip.png" :icon-size="22" @click="onDoc()"></ux-button>
<!-- #endif -->
</template>
</ux-navbar>
<ux-scroll>
<ux-card direction="column" icon="flag-filled" title="表单" :bold="true">
<ux-text text="支持任何组件,只作为数据校验"></ux-text>
</ux-card>
<ux-card direction="column" icon="arrowright" title="表单校验" :bold="true">
<ux-form ref="uxFormRef" v-model="formData" @submit="change">
<ux-form-item label="头像" field="avatar" :required="true" :min-height="68">
<ux-upload v-model="(formData['avatar'] as string)" url="https://test.api.fdproxy.cn/file/upload/add" :count="1" mode="image" align="right" :rows="false" :width="42" :height="42"></ux-upload>
</ux-form-item>
<ux-form-item label="姓名" field="name" :required="true" :rules="nameRules">
<ux-input v-model="(formData['name'] as string)" placeholder="请输入您的姓名" background="transparent" background-dark="transparent" align="right" border="none" :focus-border="false"></ux-input>
</ux-form-item>
<ux-form-item label="手机号" field="phone" :required="true" :rules="phoneRules">
<ux-input v-model="(formData['phone'] as string)" :maxlength="11" placeholder="请输入您的手机号" background="transparent" background-dark="transparent" align="right" border="none" :focus-border="false"></ux-input>
</ux-form-item>
<ux-form-item label="登录密码" field="password" :required="true" :rules="passwordRules">
<ux-input v-model="(formData['password'] as string)" :password="true" placeholder="请输入您的登录密码" background="transparent" background-dark="transparent" align="right" border="none" :focus-border="false"></ux-input>
</ux-form-item>
<ux-form-item label="性别" field="sex" :verify="false">
<ux-row justify="right">
<ux-radio-group v-model="(formData['sex'] as string)">
<ux-radio value="0" text="女神" color="#333" dark-color="#fff" :mr="10"></ux-radio>
<ux-radio value="1" text="男神" color="#333" dark-color="#fff"></ux-radio>
</ux-radio-group>
</ux-row>
</ux-form-item>
<ux-form-item label="年龄" field="age" :rules="ageRules">
<ux-keyboard mode="number" v-model="(formData['age'] as string)" :max-length="10" :show-sub="false" :show-point="false" placeholder="请输入您的年龄">
<ux-input v-model="(formData['age'] as string)" :readonly="true" placeholder="请输入您的年龄" suffix="岁" suffix-style="font-size: 12px" background="transparent" background-dark="transparent" align="right" border="none" :focus-border="false"></ux-input>
</ux-keyboard>
</ux-form-item>
<ux-form-item label="出生日期" field="date" :rules="dateRules">
<ux-datepicker selectStyle="box" mode="date" v-model="(formData['date'] as string)" btnType="bigger">
<ux-input v-model="(formData['date'] as string)" :readonly="true" placeholder="请选择您的出生日期" suffix="arrowdown" :icon-size="18" background="transparent" background-dark="transparent" align="right" border="none" :focus-border="false"></ux-input>
</ux-datepicker>
</ux-form-item>
<ux-form-item label="心情指数" field="star" :rules="starRules">
<ux-row justify="right">
<ux-rate theme="warning" v-model="(formData['star'] as number)"></ux-rate>
</ux-row>
</ux-form-item>
<ux-form-item label="您同时有几个女朋友?" field="count" :rules="countRules">
<ux-row justify="right">
<ux-numberbox v-model="(formData['count'] as number)" :min="0" :max="10"></ux-numberbox>
</ux-row>
</ux-form-item>
<ux-form-item label="您喜欢什么年龄段的女生?" field="ages" :rules="agesRules">
<ux-row justify="right" style="width: 150px;">
<ux-slider v-model="(formData['ages'] as number[])" mode="range" :min="0" :max="60" unit="岁" :show-value="true"></ux-slider>
</ux-row>
</ux-form-item>
<ux-form-item label="您结婚了吗?" field="married" :verify="false">
<ux-row justify="right">
<ux-switch v-model="(formData['married'] as boolean)"></ux-switch>
</ux-row>
</ux-form-item>
<ux-form-item label="住址" field="address" :rules="addressRules" direction="vertical" :border="false">
<ux-textarea :inner-padding="false" v-model="(formData['address'] as string)" placeholder="请输入您的详细住址" background="transparent" background-dark="transparent" border="none" :focus-border="false"></ux-textarea>
</ux-form-item>
</ux-form>
</ux-card>
<ux-placeholder :height="200">
<ux-row justify="center" align="center" style="height: 100%;">
<ux-text prefix-icon="soapbubble-filled" text="真的没有了~"></ux-text>
</ux-row>
</ux-placeholder>
</ux-scroll>
<view class="bottom" :style="backgroundColor">
<ux-button style="flex: 1;" :margin="[0, 15]" theme="primary" text="提交" @click="submit()"></ux-button>
</view>
</ux-page>
</template>
<template>
<ux-page :stack="showDoc">
<ux-navbar :title="title" :bold="true">
<template v-slot:right>
<!-- #ifndef MP -->
<ux-button theme="text" icon="/static/tip.png" :icon-size="22" @click="onDoc()"></ux-button>
<!-- #endif -->
</template>
</ux-navbar>
<ux-scroll>
<ux-card direction="column" icon="flag-filled" title="表单" :bold="true">
<ux-text text="支持任何组件,只作为数据校验"></ux-text>
</ux-card>
<ux-card direction="column" icon="arrowright" title="表单校验" :bold="true">
<ux-form ref="uxFormRef" v-model="formData" @submit="change">
<ux-form-item label="头像" field="avatar" :required="true" :min-height="68">
<ux-upload v-model="(formData['avatar'] as string)" url="https://test.api.fdproxy.cn/file/upload/add" :count="1" mode="image" align="right" :rows="false" :width="42" :height="42"></ux-upload>
</ux-form-item>
<ux-form-item label="姓名" field="name" :required="true" :rules="nameRules">
<ux-input v-model="(formData['name'] as string)" placeholder="请输入您的姓名" background="transparent" background-dark="transparent" align="right" border="none" :focus-border="false"></ux-input>
</ux-form-item>
<ux-form-item label="手机号" field="phone" :required="true" :rules="phoneRules">
<ux-input v-model="(formData['phone'] as string)" :maxlength="11" placeholder="请输入您的手机号" background="transparent" background-dark="transparent" align="right" border="none" :focus-border="false"></ux-input>
</ux-form-item>
<ux-form-item label="登录密码" field="password" :required="true" :rules="passwordRules">
<ux-input v-model="(formData['password'] as string)" :password="true" placeholder="请输入您的登录密码" background="transparent" background-dark="transparent" align="right" border="none" :focus-border="false"></ux-input>
</ux-form-item>
<ux-form-item label="性别" field="sex" :verify="false">
<ux-row justify="right">
<ux-radio-group v-model="(formData['sex'] as string)">
<ux-radio value="0" text="女神" color="#333" dark-color="#fff" :mr="10"></ux-radio>
<ux-radio value="1" text="男神" color="#333" dark-color="#fff"></ux-radio>
</ux-radio-group>
</ux-row>
</ux-form-item>
<ux-form-item label="年龄" field="age" :rules="ageRules">
<ux-keyboard mode="number" v-model="(formData['age'] as string)" :max-length="10" :show-sub="false" :show-point="false" placeholder="请输入您的年龄">
<ux-input v-model="(formData['age'] as string)" :readonly="true" placeholder="请输入您的年龄" suffix="岁" suffix-style="font-size: 12px" background="transparent" background-dark="transparent" align="right" border="none" :focus-border="false"></ux-input>
</ux-keyboard>
</ux-form-item>
<ux-form-item label="出生日期" field="date" :rules="dateRules">
<ux-datepicker selectStyle="box" mode="date" v-model="(formData['date'] as string)" btnType="bigger">
<ux-input v-model="(formData['date'] as string)" :readonly="true" placeholder="请选择您的出生日期" suffix="arrowdown" :icon-size="18" background="transparent" background-dark="transparent" align="right" border="none" :focus-border="false"></ux-input>
</ux-datepicker>
</ux-form-item>
<ux-form-item label="心情指数" field="star" :rules="starRules">
<ux-row justify="right">
<ux-rate theme="warning" v-model="(formData['star'] as number)"></ux-rate>
</ux-row>
</ux-form-item>
<ux-form-item label="您同时有几个女朋友?" field="count" :rules="countRules">
<ux-row justify="right">
<ux-numberbox v-model="(formData['count'] as number)" :min="0" :max="10"></ux-numberbox>
</ux-row>
</ux-form-item>
<ux-form-item label="您喜欢什么年龄段的女生?" field="ages" :rules="agesRules">
<ux-row justify="right" style="width: 150px;">
<ux-slider v-model="(formData['ages'] as number[])" mode="range" :min="0" :max="60" unit="岁" :show-value="true"></ux-slider>
</ux-row>
</ux-form-item>
<ux-form-item label="您结婚了吗?" field="married" :verify="false">
<ux-row justify="right">
<ux-switch v-model="(formData['married'] as boolean)"></ux-switch>
</ux-row>
</ux-form-item>
<ux-form-item label="住址" field="address" :rules="addressRules" direction="vertical" :border="false">
<ux-textarea :inner-padding="false" v-model="(formData['address'] as string)" placeholder="请输入您的详细住址" background="transparent" background-dark="transparent" border="none" :focus-border="false"></ux-textarea>
</ux-form-item>
</ux-form>
</ux-card>
<ux-placeholder :height="200">
<ux-row justify="center" align="center" style="height: 100%;">
<ux-text prefix-icon="soapbubble-filled" text="真的没有了~"></ux-text>
</ux-row>
</ux-placeholder>
</ux-scroll>
<view class="bottom" :style="backgroundColor">
<ux-button style="flex: 1;" :margin="[0, 15]" theme="primary" text="提交" @click="submit()"></ux-button>
</view>
</ux-page>
</template>
ts
<script setup>
import * as plus from '@/uni_modules/ux-plus'
import { UxFormResult, UxFormRule, useBackgroundColor } from '@/uni_modules/ux-frame'
const title = ref('')
const backgroundColor = computed((): string => {
return `background-color: ${useBackgroundColor('#fff', '#333')}`
})
const uxFormRef = ref<UxFormComponentPublicInstance | null>(null)
const formData = ref<UTSJSONObject>({
name: '',
phone: '',
password: '',
avatar: '',
sex: '1',
age: '',
date: '',
star: 0,
count: 0,
ages: [25, 40],
married: false,
address: '',
})
const nameRules = [{
type: 'string',
valid: (val: any): string => {
let value = val as string
if(value.length < 2 || value.length > 8) {
return '姓名只支持2-8个字符长度'
}
return ''
}
}] as UxFormRule[]
const phoneRules = [{
type: 'string',
valid: (val: any): string => {
let value = val as string
if(value.length != 11) {
return '手机号只支持11个字符长度'
}
return ''
}
}] as UxFormRule[]
const passwordRules = [{
type: 'string',
valid: (val: any): string => {
let value = val as string
if(value.length < 8) {
return '密码最少8个字符长度'
}
return ''
}
}] as UxFormRule[]
const ageRules = [{
type: 'string',
valid: (val: any): string => {
let value = val as string
if(value == '') {
return '请填写您的年龄'
}
if(parseInt(value) > 100) {
return '您是千年老妖吗?'
}
return ''
}
}] as UxFormRule[]
const dateRules = [{
type: 'string',
valid: (val: any): string => {
let value = val as string
if(value == '') {
return '出生日期不能为空'
}
return ''
}
}] as UxFormRule[]
const starRules = [{
type: 'number',
valid: (val: any): string => {
let value = val as number
if(value == 0) {
return '请选择心情指数'
}
return ''
}
}] as UxFormRule[]
const countRules = [{
type: 'number',
valid: (val: any): string => {
let value = val as number
if(value > 1) {
return '大哥,您犯法了!'
}
return ''
}
}] as UxFormRule[]
const agesRules = [{
type: 'array',
valid: (val: any): string => {
let value = val as number[]
if(value[0] < 16) {
return '保护未成年!'
}
return ''
}
}] as UxFormRule[]
const addressRules = [{
type: 'string',
valid: (val: any): string => {
let value = val as string
if(value == '') {
return '住址不能为空'
}
return ''
}
}] as UxFormRule[]
function submit() {
let result = uxFormRef.value?.$callMethod('submit') as UxFormResult
if(!result.valid) {
uni.showToast({
title: result.error,
icon: 'none'
})
}
}
function change(e: UxFormResult) {
console.log(e);
}
onLoad((e) => {
title.value = e['title'] ?? ''
})
const showDoc = ref(false)
function onDoc() {
plus.openWeb({
title: '在线文档',
url: 'https://www.uxframe.cn/component/form.html',
// blur: 1,
success: () => {
showDoc.value = true
},
complete: () => {
showDoc.value = false
}
})
}
</script>
<script setup>
import * as plus from '@/uni_modules/ux-plus'
import { UxFormResult, UxFormRule, useBackgroundColor } from '@/uni_modules/ux-frame'
const title = ref('')
const backgroundColor = computed((): string => {
return `background-color: ${useBackgroundColor('#fff', '#333')}`
})
const uxFormRef = ref<UxFormComponentPublicInstance | null>(null)
const formData = ref<UTSJSONObject>({
name: '',
phone: '',
password: '',
avatar: '',
sex: '1',
age: '',
date: '',
star: 0,
count: 0,
ages: [25, 40],
married: false,
address: '',
})
const nameRules = [{
type: 'string',
valid: (val: any): string => {
let value = val as string
if(value.length < 2 || value.length > 8) {
return '姓名只支持2-8个字符长度'
}
return ''
}
}] as UxFormRule[]
const phoneRules = [{
type: 'string',
valid: (val: any): string => {
let value = val as string
if(value.length != 11) {
return '手机号只支持11个字符长度'
}
return ''
}
}] as UxFormRule[]
const passwordRules = [{
type: 'string',
valid: (val: any): string => {
let value = val as string
if(value.length < 8) {
return '密码最少8个字符长度'
}
return ''
}
}] as UxFormRule[]
const ageRules = [{
type: 'string',
valid: (val: any): string => {
let value = val as string
if(value == '') {
return '请填写您的年龄'
}
if(parseInt(value) > 100) {
return '您是千年老妖吗?'
}
return ''
}
}] as UxFormRule[]
const dateRules = [{
type: 'string',
valid: (val: any): string => {
let value = val as string
if(value == '') {
return '出生日期不能为空'
}
return ''
}
}] as UxFormRule[]
const starRules = [{
type: 'number',
valid: (val: any): string => {
let value = val as number
if(value == 0) {
return '请选择心情指数'
}
return ''
}
}] as UxFormRule[]
const countRules = [{
type: 'number',
valid: (val: any): string => {
let value = val as number
if(value > 1) {
return '大哥,您犯法了!'
}
return ''
}
}] as UxFormRule[]
const agesRules = [{
type: 'array',
valid: (val: any): string => {
let value = val as number[]
if(value[0] < 16) {
return '保护未成年!'
}
return ''
}
}] as UxFormRule[]
const addressRules = [{
type: 'string',
valid: (val: any): string => {
let value = val as string
if(value == '') {
return '住址不能为空'
}
return ''
}
}] as UxFormRule[]
function submit() {
let result = uxFormRef.value?.$callMethod('submit') as UxFormResult
if(!result.valid) {
uni.showToast({
title: result.error,
icon: 'none'
})
}
}
function change(e: UxFormResult) {
console.log(e);
}
onLoad((e) => {
title.value = e['title'] ?? ''
})
const showDoc = ref(false)
function onDoc() {
plus.openWeb({
title: '在线文档',
url: 'https://www.uxframe.cn/component/form.html',
// blur: 1,
success: () => {
showDoc.value = true
},
complete: () => {
showDoc.value = false
}
})
}
</script>
css
<style lang="scss">
.bottom {
position: fixed;
bottom: 0;
width: 100%;
height: 54px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
background-color: white;
}
</style>
<style lang="scss">
.bottom {
position: fixed;
bottom: 0;
width: 100%;
height: 54px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
background-color: white;
}
</style>