Skip to content
本页导读

Form

组件类型:UxFormComponentPublicInstance

支持任何组件,只作为数据校验

平台兼容性

UniApp X

AndroidiOSweb鸿蒙 Next小程序
x

UniApp Vue Nvue

AndroidiOSweb鸿蒙 Next小程序
xxxx

Props

属性名类型默认值说明
directionStringhorizontal布局方向
widthAny自适应宽度
sizeAny$ux.Conf.fontSize字体大小
errorSizeAny11错误提示字体大小
colorString$ux.Conf.fontColor字体颜色
darkColorString深色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>