# Form 表单
### 介绍
用于数据录入、校验,支持输入框、单选框、复选框、文件上传等类型,需要与 Cell 组件搭配使用。
### 安装
``` javascript
import { createApp } from 'vue';
// vue
import { Form,FormItem,Cell,CellGroup } from '@nutui/nutui';
// taro
import { Form,FormItem,Cell,CellGroup } from '@nutui/nutui-taro';
const app = createApp();
app.use(Form);
app.use(FormItem);
app.use(Cell);
app.use(CellGroup);
```
### 基础用法
``` html
```
### 动态表单
``` html
添加
删除
提交
```
``` javascript
setup(){
const dynamicRefForm = ref(null);
const dynamicForm = {
state: reactive({
name: '',
tels: new Array({
key: 1,
value: ''
})
}),
methods: {
submit() {
dynamicRefForm.value.validate().then(({ valid, errors }: any) => {
if (valid) {
console.log('success', dynamicForm);
} else {
console.log('error submit!!', errors);
}
});
},
remove() {
dynamicForm.state.tels.splice(dynamicForm.state.tels.length - 1, 1);
},
add() {
let newIndex = dynamicForm.state.tels.length;
dynamicForm.state.tels.push({
key: Date.now(),
value: ''
});
}
}
};
return {
dynamicForm,
dynamicRefForm
};
}
```
### 表单校验
``` html
提交
重置提示状态
```
``` javascript
setup(){
const formData = reactive({
name: '',
age: '',
tel: '',
address: ''
});
const validate = (item: any) => {
console.log(item);
};
const ruleForm = ref(null);
const submit = () => {
ruleForm.value.validate().then(({ valid, errors }: any) => {
if (valid) {
console.log('success', formData);
} else {
console.log('error submit!!', errors);
}
});
};
const reset = () => {
ruleForm.value.reset();
};
// 失去焦点校验
const customBlurValidate = (prop: string) => {
ruleForm.value.validate(prop).then(({ valid, errors }: any) => {
if (valid) {
console.log('success', formData);
} else {
console.log('error submit!!', errors);
}
});
};
// 函数校验
const customValidator = (val: string) => /^\d+$/.test(val);
// Promise 异步校验
const asyncValidator = (val: string) => {
return new Promise((resolve) => {
Toast.loading('模拟异步验证中...');
setTimeout(() => {
Toast.hide();
resolve(/^400(-?)[0-9]{7}$|^1\d{10}$|^0[0-9]{2,3}-[0-9]{7,8}$/.test(val));
}, 1000);
});
};
return { ruleForm, formData, validate, customValidator, asyncValidator, customBlurValidate, submit, reset };
}
```
### 表单类型
``` html
复选框
选项1
选项2
选项3
```
``` javascript
setup(){
const formData2 = reactive({
switch: false,
checkbox: false,
radio: 0,
number: 0,
rate: 3,
range: 30,
address: '',
defaultFileList: [
{
name: '文件1.png',
url: 'https://m.360buyimg.com/babel/jfs/t1/164410/22/25162/93384/616eac6cE6c711350/0cac53c1b82e1b05.gif',
status: 'success',
message: '上传成功',
type: 'image'
},
{
name: '文件2.png',
url: 'https://m.360buyimg.com/babel/jfs/t1/164410/22/25162/93384/616eac6cE6c711350/0cac53c1b82e1b05.gif',
status: 'uploading',
message: '上传中...',
type: 'image'
}
]
});
const addressModule = reactive({
state: {
show: false,
province: [
{ id: 1, name: '北京' },
{ id: 2, name: '广西' },
{ id: 3, name: '江西' },
{ id: 4, name: '四川' }
],
city: [
{ id: 7, name: '朝阳区' },
{ id: 8, name: '崇文区' },
{ id: 9, name: '昌平区' },
{ id: 6, name: '石景山区' }
],
country: [
{ id: 3, name: '八里庄街道' },
{ id: 9, name: '北苑' },
{ id: 4, name: '常营乡' }
],
town: []
},
methods: {
show() {
addressModule.state.show = !addressModule.state.show;
if (addressModule.state.show) {
formData2.address = '';
}
},
onChange({ custom, next, value }: any) {
formData2.address += value.name;
const name = addressModule.state[next];
if (name.length < 1) {
addressModule.state.show = false;
}
}
}
});
return { formData2, addressModule };
}
```
### Form Props
| 参数 | 说明 | 类型 | 默认值 |
|-------------|--------------------------------------|--------|--------|
| model-value | 表单数据对象(使用表单校验时,_必填_) | object | |
### Form Events
| 事件名 | 说明 | 回调参数 |
|----------|----------------------------|------------------------------------------------------------|
| validate | 任一表单项被校验失败后触发 | 被校验的表单项 prop 值,校验是否通过,错误消息(如果存在) |
### FormItem Props
| 参数 | 说明 | 类型 | 默认值 |
|---------------------|------------------------------------------------------------------|------------------|---------|
| required | 是否显示必填字段的标签旁边的红色星号 | boolean | `false` |
| prop | 表单域 v-model 字段, 在使用表单校验功能的情况下,该属性是必填的 | string | - |
| label-width | 表单项 label 宽度,默认单位为`px` | number \| string | `90px` |
| label-align | 表单项 label 对齐方式,可选值为 `center` `right` | string | `left` |
| body-align | 输入框对齐方式,可选值为 `center` `right` | string | `left` |
| error-message-align | 错误提示文案对齐方式,可选值为 `center` `right` | string | `left` |
| show-error-line | 是否在校验不通过时标红输入框 | boolean | `true` |
| show-error-message | 是否在校验不通过时在输入框下方展示错误提示 | boolean | `true` |
### FormItem Rule 数据结构
使用 FormItem 的`rules`属性可以定义校验规则,可选属性如下:
| 键名 | 说明 | 类型 |
|-----------|------------------------|-----------------------------------------------|
| required | 是否为必选字段 | boolean |
| message | 错误提示文案 | string |
| validator | 通过函数进行校验 | (value, rule) => boolean \| string \| Promise |
| regex | 通过正则表达式进行校验 | RegExp |
### Methods
通过 [ref](https://v3.cn.vuejs.org/api/special-attributes.html#ref) 可以获取到 Form 实例并调用实例方法
| 方法名 | 说明 | 参数 | 返回值 |
|-------------------|--------------------------------------------------------------------|---------------------|---------|
| submit | 提交表单进行校验的方法 | - | Promise |
| reset | 清空校验结果 | - | - |
| validate`v3.1.13` | 用户主动触发校验,用于用户自定义场景时触发,例如 blur、change 事件 | 同 FormItem prop 值 | - |