Form 表单
优质
小牛编辑
135浏览
2023-12-01
由输入框、选择器、单选框、多选框等控件组成,用以收集、校验、提交数据。
我们为表单添加了 Angular 的响应式支持,你可以在为表单定义多种状态,并从各类组件中收集变化与数据流,这会让你的 应用更具表现力,并更容易梳理、扩展与测试。
如果你对这一编程风格不太了解,可以考虑先从官方文档学习开始 Reactive Forms。当然除此之外,你仍旧可以使用熟悉模板驱动方式编程。
输入框表单
除了显示错误反馈之外,携带输入框的表单还能显示相应的图标。
<el-form [formGroup]="validateForm" label-width="100px" [show-icon]="true" [show-message]="true" el-class="form-demo"> <el-form-item label="邮箱" [required]="true" [status]="statusCtrl('mail')" [error]="messageCtrl('mail')"> <el-input formControlName="mail"></el-input> </el-form-item> <el-form-item label="密码" [required]="true" [status]="statusCtrl('password')" [error]="messageCtrl('password')"> <el-input formControlName="password" native-type="password"></el-input> </el-form-item> <el-form-item> <el-button type="primary" (click)="submit()">提交</el-button> <el-button (click)="reset()">重置</el-button> </el-form-item> </el-form> <script type="text"> // in Component: validateForm: FormGroup constructor( @Inject(forwardRef(() => FormBuilder)) private formBuilder: FormBuilder ) { } submit(): void { console.log(this.validateForm.value) } reset(): void { this.validateForm.reset() } ctrl(item: string): AbstractControl { return this.validateForm.controls[item] } statusCtrl(item: string): string { if (!this.validateForm.controls[item]) return const control: AbstractControl = this.validateForm.controls[item] return control.dirty && control.hasError('status') ? control.errors.status : '' } messageCtrl(item: string): string { if (!this.validateForm.controls[item]) return const control: AbstractControl = this.validateForm.controls[item] return control.dirty && control.hasError('message') ? control.errors.message : '' } ngOnInit(): void { this.validateForm = this.formBuilder.group({ password: [ '', [this.passwordValidator] ], mail: [ '', [this.emailValidator] ], }) } private emailValidator = (control: FormControl): validateResult => { const mailReg: RegExp = /^[A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$/ if (!mailReg.test(control.value)) { return { status: 'error', message: '邮箱格式不正确' } } return { status: 'success' } } private passwordValidator = (control: FormControl): validateResult => { if (!control.value) { return { status: 'error', message: '密码是必填的' } } if (control.value.length < 6) { return { status: 'error', message: '密码长度必须大于 6 位' } } return { status: 'success' } } </script>
包含多种元素的表单
包括各种表单项,比如输入框、选择器、开关、单选框、多选框等。
<el-form [formGroup]="validateForm" label-width="100px" size="small" [show-icon]="true" [show-message]="true" el-class="form-demo"> <el-form-item label="城市" [required]="true" [status]="statusCtrl('city')" [error]="messageCtrl('city')"> <el-input formControlName="city"></el-input> </el-form-item> <el-form-item label="规格"> <el-cascader [options]="options" [change-on-select]="true" formControlName="spec"></el-cascader> </el-form-item> <el-form-item label="配送日期" [status]="statusCtrl('date')" [error]="messageCtrl('date')" > <el-date-picker formControlName="date" [format]="'yyyy-MM-dd'"></el-date-picker> </el-form-item> <el-form-item label="配送方式"> <el-radio-group formControlName="express"> <el-radio label="eleme">蜂鸟配送</el-radio> <el-radio label="shop">商家配送</el-radio> </el-radio-group> </el-form-item> <el-form-item label="发票"> <el-checkbox formControlName="invoice">需要发票</el-checkbox> </el-form-item> <el-form-item label="使用折扣"> <el-checkbox-group formControlName="discount" (modelChange)="discount"> <el-checkbox label="discount1">折扣1</el-checkbox> <el-checkbox label="discount2">折扣2</el-checkbox> <el-checkbox label="discount3">折扣3</el-checkbox> <el-checkbox label="禁用" [elDisabled]="true">vip 折扣</el-checkbox> </el-checkbox-group> </el-form-item> <el-form-item label="配送时间" [status]="statusCtrl('time')" [error]="messageCtrl('time')"> <el-select placeholder="请选择" formControlName="time" [clearable]="true" [multiple]="true"> <el-option label="尽快配送" value="now"></el-option> <el-option label="夜间配送" value="night"></el-option> </el-select> </el-form-item> <el-form-item> <el-button type="primary" (click)="submit()">提交</el-button> </el-form-item> </el-form> <script type="text"> // in Component: labelPosition: string = 'left' validateForm: FormGroup options: any[] = [{ value: 'mike', label: '加奶油', children: [{ value: 'hot', label: '热奶油', children: [{ value: 'more', label: '多糖', }, { value: 'half', label: '半糖', }, { value: 'few', label: '少糖', }], }], }, { value: 'cafe', label: '加咖啡', children: [{ value: 'cubita', label: '古巴咖啡', }, { value: 'brazil', label: '巴西咖啡', }, { value: 'jamaica', label: '牙买加咖啡', }, { value: 'mamba', label: '曼巴咖啡', }], }] constructor( @Inject(forwardRef(() => FormBuilder)) private formBuilder: FormBuilder ) { } submit(): void { console.log(this.validateForm.value) } reset(): void { this.validateForm.reset() } ctrl(item: string): AbstractControl { return this.validateForm.controls[item] } statusCtrl(item: string): string { if (!this.validateForm.controls[item]) return const control: AbstractControl = this.validateForm.controls[item] return control.dirty && control.hasError('status') ? control.errors.status : '' } messageCtrl(item: string): string { if (!this.validateForm.controls[item]) return const control: AbstractControl = this.validateForm.controls[item] return control.dirty && control.hasError('message') ? control.errors.message : '' } ngOnInit(): void { this.validateForm = this.formBuilder.group({ city: [ '', [this.cityValidator] ], express: [ '' ], invoice: [ '' ], discount: [ [] ], time: [ '', [this.timeValidator] ], num: [ 1 ], spec: [ '' ], date: [ '', [this.dateValidator] ], }) } private timeValidator = (control: FormControl): validateResult => { if (!control.value) { return { status: 'error', message: '必须选择配送时间' } } return { status: 'success' } } private dateValidator = (control: FormControl): validateResult => { if (!control.value) { return { status: 'error', message: '必须选择配送日期' } } return { status: 'success' } } private cityValidator = (control: FormControl): validateResult => { if (!control.value) { return { status: 'error', message: '必须填写城市名' } } if (!/[\u4e00-\u9fa5]/.test(control.value)) { return { status: 'error', message: '城市名必须是中文' } } return { status: 'success' } } </script>
对齐方式
根据具体目标和制约因素,选择最佳的标签对齐方式。
<el-radio-group [(model)]="labelPosition" size="small"> <el-radio-button label="left">左对齐</el-radio-button> <el-radio-button label="right">右对齐</el-radio-button> <el-radio-button label="top">顶部对齐</el-radio-button> </el-radio-group> <div style="margin: 20px;"></div> <el-form [formGroup]="validateForm" label-width="100px" size="small" el-class="form-demo" [label-position]="labelPosition"> <el-form-item label="早餐"> <el-input></el-input> </el-form-item> <el-form-item label="午餐"> <el-input></el-input> </el-form-item> <el-form-item> <el-button type="primary">提交</el-button> </el-form-item> </el-form>
行内表单
当垂直方向空间受限且表单较简单时,可以在一行内放置表单。
<el-form [formGroup]="validateForm" [inline]="true" size="small"> <el-form-item label="年龄"> <el-input></el-input> </el-form-item> <el-form-item label="姓名"> <el-input></el-input> </el-form-item> <el-form-item> <el-button type="primary">搜索</el-button> </el-form-item> </el-form>
Form Attributes
参数 | 说明 | 类型 | 可选值 | 默认值 |
---|---|---|---|---|
inline | 是否行内显示 | boolean | ||
show-icon | 是否显示辅助状态图标 (仅对 Input 有效) | boolean | ||
show-message | 是否显示错误提示信息 | boolean | ||
label-position | label 对齐方式 | string | right | |
label-width | label 宽度 | string |
Form Item Attributes
参数 | 说明 | 类型 | 可选值 | 默认值 |
---|---|---|---|---|
status | 当前表单项状态 | string | error / success / validating | |
label | label 文字描述 | string | ||
error | 校验错误信息 | string | ||
show-message | 是否显示错误提示信息 (仅对单个表单项设置) | boolean | 1 | |
inline-message | 行内展示校验错误信息 | boolean | ||
label-width | label 宽度 (仅对单个表单项设置) | string | ||
required | 表单项是否为必填 (UI 辅助标注为必填) | boolean |