# 表单(form)

封装el-form与el-row组件,由输入框、选择器、单选框、多选框等控件组成,用以收集、校验、提交数据

TIP

参考ElementUI文档Form 表单 (opens new window)

# 典型表单

包括各种表单项,比如输入框、选择器、开关、单选框、多选框等。

立即创建
<itv-form ref="form" :model="form" label-width="80px">
  <itv-form-input label="活动名称" v-model="form.name"></itv-form-input>
  <el-button type="primary" @click="onSubmit">立即创建</el-button>
</itv-form>
<script>
  export default {
    data() {
      return {
        form: {
          name: '',
        }
      }
    },
    methods: {
      onSubmit() {
        console.log('submit');
      }
    }
  }
</script>
Expand Copy

TIP

W3C 标准中有如下规定 (opens new window)

When there is only one single-line text input field in a form, the user agent should accept Enter in that field as a request to submit the form.

即:当一个 form 元素中只有一个输入框时,在该输入框中按下回车应提交该表单。如果希望阻止这一默认行为,可以在 <el-form> 标签上添加 @submit.native.prevent

# 对齐方式

根据具体目标和制约因素,选择最佳的标签对齐方式。

左对齐 右对齐 顶部对齐

通过设置 label-position 属性可以改变表单域标签的位置,可选值为 topleft ,当设为 top 时标签会置于表单域的顶部

<el-radio-group v-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>
<itv-form :label-position="labelPosition" label-width="80px" :model="formLabelAlign">
  <itv-form-input label="活动名称" v-model="formLabelAlign.name"></itv-form-input>
  <itv-form-input label="活动区域" v-model="formLabelAlign.region"></itv-form-input>
  <itv-form-input label="活动形式" v-model="formLabelAlign.type"></itv-form-input>
</itv-form>
<script>
  export default {
    data() {
      return {
        labelPosition: 'right',
        formLabelAlign: {
          name: '',
          region: '',
          type: ''
        }
      };
    }
  }
</script>
Expand Copy

# 表单验证

在防止用户犯错的前提下,尽可能让用户更早地发现并纠正错误。

立即创建 重置

Form 组件提供了表单验证的功能,只需要通过 rules 属性传入约定的验证规则,并将 Form-Item 的 prop 属性设置为需校验的字段名即可。校验规则参见 async-validator (opens new window)

<itv-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px">
  <itv-form-input label="活动名称" v-model="ruleForm.name" prop="name"></itv-form-input>
  <itv-form-input label="活动区域" v-model="ruleForm.region" prop="region"></itv-form-input>
  <itv-form-input label="活动形式" v-model="ruleForm.desc" prop="desc"></itv-form-input>
  <el-button type="primary" @click="submitForm('ruleForm')">立即创建</el-button>
  <el-button @click="resetForm('ruleForm')">重置</el-button>
</itv-form>
<script>
  export default {
    data() {
      return {
        ruleForm: {
          name: '',
          region: '',
          desc: ''
        },
        rules: {
          name: [
            { required: true, message: '请输入活动名称', trigger: 'blur' },
            { min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' }
          ],
          region: [
            { required: true, message: '请选择活动区域', trigger: 'change' }
          ],
          desc: [
            { required: true, message: '请填写活动形式', trigger: 'blur' }
          ]
        }
      };
    },
    methods: {
      submitForm(formName) {
        this.$refs[formName].validate((valid) => {
          if (valid) {
            alert('success submit');
          } else {
            console.log('error submit');
            return false;
          }
        });
      },
      resetForm(formName) {
        this.$refs[formName].resetFields();
      }
    }
  }
</script>
Expand Copy

# 自定义校验规则

这个例子中展示了如何使用自定义验证规则来完成密码的二次验证。

提交 重置

本例还使用 status-icon 属性为输入框添加了表示校验结果的反馈图标。

<itv-form :model="ruleForm" status-icon :rules="rules" ref="ruleForm" label-width="100px">
  <itv-form-input label="密码" v-model="ruleForm.pass" autocomplete="off" prop="pass"></itv-form-input>
  <itv-form-input label="确认密码" v-model="ruleForm.checkPass" autocomplete="off" prop="checkPass"></itv-form-input>
  <itv-form-input-number label="年龄" v-model.number="ruleForm.age" prop="age"></itv-form-input-number>
  <el-button type="primary" @click="submitForm('ruleForm')">提交</el-button>
  <el-button @click="resetForm('ruleForm')">重置</el-button>
</itv-form>
<script>
  export default {
    data() {
      var checkAge = (rule, value, callback) => {
        if (!value) {
          return callback(new Error('年龄不能为空'));
        }
        setTimeout(() => {
          console.log(value)
          if (!Number.isInteger(value)) {
            callback(new Error('请输入数字值'));
          } else {
            if (value < 18) {
              callback(new Error('必须年满18岁'));
            } else {
              callback();
            }
          }
        }, 1000);
      };
      var validatePass = (rule, value, callback) => {
        if (value === '') {
          callback(new Error('请输入密码'));
        } else {
          if (this.ruleForm.checkPass !== '') {
            this.$refs.ruleForm.validateField('checkPass');
          }
          callback();
        }
      };
      var validatePass2 = (rule, value, callback) => {
        if (value === '') {
          callback(new Error('请再次输入密码'));
        } else if (value !== this.ruleForm.pass) {
          callback(new Error('两次输入密码不一致!'));
        } else {
          callback();
        }
      };
      return {
        ruleForm: {
          pass: '',
          checkPass: '',
          age: ''
        },
        rules: {
          pass: [
            { validator: validatePass, trigger: 'blur' }
          ],
          checkPass: [
            { validator: validatePass2, trigger: 'blur' }
          ],
          age: [
            { validator: checkAge, trigger: 'blur' }
          ]
        }
      };
    },
    methods: {
      submitForm(formName) {
        this.$refs[formName].validate((valid) => {
          if (valid) {
            alert('success submit');
          } else {
            console.log('error submit');
            return false;
          }
        });
      },
      resetForm(formName) {
        this.$refs[formName].resetFields();
      }
    }
  }
</script>
Expand Copy

TIP

自定义校验 callback 必须被调用。 更多高级用法可参考 async-validator (opens new window)

# 数字类型验证

提交 重置

数字类型的验证需要在 v-model 处加上 .number 的修饰符,这是 Vue 自身提供的用于将绑定值转化为 number 类型的修饰符。

<itv-form :model="numberValidateForm" ref="numberValidateForm" label-width="100px">
  <itv-form-input label="年龄" prop="age" :rules="{ type: 'number', message: '年龄必须为数字值'}" v-model.number="numberValidateForm.age" autocomplete="off"></itv-form-input>
  <el-button type="primary" @click="submitForm('numberValidateForm')">提交</el-button>
  <el-button @click="resetForm('numberValidateForm')">重置</el-button>
</itv-form>
<script>
  export default {
    data() {
      return {
        numberValidateForm: {
          age: ''
        }
      };
    },
    methods: {
      submitForm(formName) {
        this.$refs[formName].validate((valid) => {
          if (valid) {
            alert('success submit');
          } else {
            console.log('error submit');
            return false;
          }
        });
      },
      resetForm(formName) {
        this.$refs[formName].resetFields();
      }
    }
  }
</script>
Expand Copy

# Attributes

参数 说明 类型 可选值 默认值
gutter 间距,封装el-row组件 number
model 表单数据对象 object
rules 表单验证规则 object
label-position 表单域标签的位置,如果值为 left 或者 right 时,则需要设置 label-width string right/left/top right
label-width 表单域标签的宽度,例如 '50px'。作为 Form 直接子元素的 form-item 会继承该值。支持 auto string
label-suffix 表单域标签的后缀 string
hide-required-asterisk 是否隐藏必填字段的标签旁边的红色星号 boolean false
show-message 是否显示校验错误信息 boolean true
inline-message 是否以行内形式展示校验信息 boolean false
status-icon 是否在输入框中显示校验结果反馈图标 boolean false
validate-on-rule-change 是否在 rules 属性改变后立即触发一次验证 boolean true
size 用于控制该表单内组件的尺寸 string medium / small / mini
disabled 是否禁用该表单内的所有组件。若设置为 true,则表单内组件上的 disabled 属性不再生效 boolean false

# Methods

方法名 说明 参数
validate 对整个表单进行校验的方法,参数为一个回调函数。该回调函数会在校验结束后被调用,并传入两个参数:是否校验成功和未通过校验的字段。若不传入回调函数,则会返回一个 promise Function(callback: Function(boolean, object))
validateField 对部分表单字段进行校验的方法 Function(props: array | string, callback: Function(errorMessage: string))
resetFields 对整个表单进行重置,将所有字段值重置为初始值并移除校验结果
clearValidate 移除表单项的校验结果。传入待移除的表单项的 prop 属性或者 prop 组成的数组,如不传则移除整个表单的校验结果 Function(props: array | string)

# Events

事件名称 说明 回调参数
validate 任一表单项被校验后触发 被校验的表单项 prop 值,校验是否通过,错误消息(如果存在)
上次更新: 12/28/2023, 5:33:41 PM