Form 表单

具有数据收集、校验和提交功能的表单,包含复选框、单选框、输入框、下拉选择框等元素。

表单

我们为 form 提供了以下两种排列方式:

  • 水平排列:标签和表单控件水平排列;(默认)
  • 垂直排列:标签和表单控件上下垂直排列;
  • 行内排列:表单项水平行内排列。

表单域

表单一定会包含表单域,表单域可以是输入控件,标准表单域,标签,下拉菜单,文本域等。这里我们封装了表单域 <Form.Item />

组件演示

平行排列

行内排列,常用于登录界面。

  1. <v-form>
  2. <v-form-item label="账户">
  3. <v-input placeholder="请输入账户名"></v-input>
  4. </v-form-item>
  5. <v-form-item label="密码">
  6. <v-input placeholder="请输入密码"></v-input>
  7. </v-form-item>
  8. <v-form-item>
  9. <v-checkbox>记住我</v-checkbox>
  10. </v-form-item>
  11. <v-form-item>
  12. <v-button type="primary" html-type="submit">登录</v-button>
  13. </v-form-item>
  14. </v-form>
  15. <br>
  16. <v-form>
  17. <v-form-item>
  18. <v-input placeholder="用户名">
  19. <v-icon type="user" slot="before"></v-icon>
  20. </v-input>
  21. </v-form-item>
  22. <v-form-item>
  23. <v-input placeholder="密码" type="password">
  24. <v-icon type="lock" slot="before"></v-icon>
  25. </v-input>
  26. </v-form-item>
  27. <v-form-item>
  28. <v-button type="primary" html-type="submit">登录</v-button>
  29. </v-form-item>
  30. </v-form>

垂直排列

垂直排列布局

  1. <v-form direction="vertical">
  2. <v-form-item label="用户名">
  3. <v-input type="text" placeholder="用户名" size="large"></v-input>
  4. </v-form-item>
  5. <v-form-item label="密码" required>
  6. <v-input type="password" placeholder="密码" size="large"></v-input>
  7. </v-form-item>
  8. <v-form-item style="margin-top:24px">
  9. <v-button type="primary" html-type="submit">确定</v-button>
  10. </v-form-item>
  11. </v-form>

典型排列

竖直排列的表单。

  1. <template>
  2. <v-form direction="horizontal">
  3. <v-form-item label="用户名" :label-col="labelCol" :wrapper-col="wrapperCol">
  4. <span class="ant-form-text" id="userName" name="userName">大眼萌 minion</span>
  5. </v-form-item>
  6. <v-form-item label="密码" :label-col="labelCol" :wrapper-col="wrapperCol" required>
  7. <v-input type="password" placeholder="请输入密码" size="large"></v-input>
  8. </v-form-item>
  9. <v-form-item label="您的性别" :label-col="labelCol" :wrapper-col="wrapperCol">
  10. <v-radio-group value="female" :data="[{value: 'male', text: '男的'},{value: 'female', text: '女的'}]"></v-radio-group>
  11. </v-form-item>
  12. <v-form-item label="备注" :label-col="labelCol" :wrapper-col="wrapperCol">
  13. <v-input type="textarea" placeholder="随便写"></v-input>
  14. </v-form-item>
  15. <v-form-item label="卖身华府" :label-col="labelCol" :wrapper-col="wrapperCol">
  16. <v-checkbox>同意</v-checkbox>
  17. </v-form-item>
  18. <v-form-item :wrapper-col="{span:16,offset:6}" style="margin-top:24px">
  19. <v-button type="primary" html-type="submit">确定</v-button>
  20. </v-form-item>
  21. </v-form>
  22. </template>
  23. <script>
  24. export default {
  25. data:()=> ({
  26. labelCol: {
  27. span: 6
  28. },
  29. wrapperCol: {
  30. span: 14
  31. }
  32. })
  33. }
  34. </script>

校验提示

我们为表单控件定义了三种校验状态,为 定义 validateStatus 属性即可。 validateStatus: 'success', 'warning', 'error', 'validating'。 另外为输入框添加反馈图标,设置 <formitem> 的 hasFeedback 属性值为 true 即可。 注意: 反馈图标只对 <v-input> 有效。

  1. <template>
  2. <v-form direction="horizontal">
  3. <v-form-item label="失败校验" :label-col="labelCol" :wrapper-col="wrapperCol" help="请输入数字和字母的组合" validate-status="error">
  4. <v-input value="无效选择" size="large"></v-input>
  5. </v-form-item>
  6. <v-form-item label="警告校验" :label-col="labelCol" :wrapper-col="wrapperCol" validate-status="warning">
  7. <v-input value="前方高能预警" size="large"></v-input>
  8. </v-form-item>
  9. <v-form-item label="校验中" :label-col="labelCol" :wrapper-col="wrapperCol" help="信息审核中..." has-feedback validate-status="validating">
  10. <v-input value="我是被校验的内容" size="large"></v-input>
  11. </v-form-item>
  12. <v-form-item label="成功校验" :label-col="labelCol" :wrapper-col="wrapperCol" has-feedback validate-status="success">
  13. <v-input value="我是正文" size="large"></v-input>
  14. </v-form-item>
  15. <v-form-item label="警告校验" :label-col="labelCol" :wrapper-col="wrapperCol" has-feedback validate-status="warning">
  16. <v-input value="前方高能预警" size="large"></v-input>
  17. </v-form-item>
  18. <v-form-item label="失败校验" :label-col="labelCol" :wrapper-col="wrapperCol" help="请输入数字和字母的组合" has-feedback validate-status="error">
  19. <v-input value="无效选择" size="large"></v-input>
  20. </v-form-item>
  21. </v-form>
  22. </template>
  23. <script>
  24. export default {
  25. data:()=> ({
  26. labelCol: {
  27. span: 6
  28. },
  29. wrapperCol: {
  30. span: 14
  31. }
  32. })
  33. }
  34. </script>

表单校验

Form 组件提供了表单验证的功能,只需要通过 rule 属性传入约定的验证规则,并将 <formitem>prop 属相设置为需校验的字段名即可。校验规则参见async-validator

  1. <template>
  2. <v-form direction="horizontal" :model="ruleForm" :rules="rules" ref="ruleForm">
  3. <v-form-item label="活动名称" :label-col="labelCol" :wrapper-col="wrapperCol" prop="name" has-feedback>
  4. <v-input size="large" v-model="ruleForm.name"></v-input>
  5. </v-form-item>
  6. <v-form-item label="活动区域" :label-col="labelCol" :wrapper-col="wrapperCol" prop="region">
  7. <v-select v-model="ruleForm.region" placeholder="请选择活动区域" notfound="无法找到" :data="[{value: '1', label: '区域1'}, {value: '2', label: '区域2'}]"></v-select>
  8. </v-form-item>
  9. <v-form-item label="活动时间" :label-col="labelCol" :wrapper-col="wrapperCol" prop="date">
  10. <v-date-picker v-model="ruleForm.date"></v-date-picker>
  11. </v-form-item>
  12. <v-form-item label="即时配送" :label-col="labelCol" :wrapper-col="wrapperCol">
  13. <v-switch v-model="ruleForm.delivery"></v-switch>
  14. </v-form-item>
  15. <v-form-item label="活动性质" :label-col="labelCol" :wrapper-col="wrapperCol" prop="type">
  16. <v-checkbox-group v-model="ruleForm.type" :data="checkboxOpt"></v-checkbox-group>
  17. </v-form-item>
  18. <v-form-item label="特殊资源" :label-col="labelCol" :wrapper-col="wrapperCol" prop="resource">
  19. <v-radio-group v-model="ruleForm.resource" :data="[{value: '1', text: '线上品牌商赞助'},{value: '2', text: '线下场地免费'}]"></v-radio-group>
  20. </v-form-item>
  21. <v-form-item label="活动形式" :label-col="labelCol" :wrapper-col="wrapperCol" prop="desc">
  22. <v-input v-model="ruleForm.desc" type="textarea"></v-input>
  23. </v-form-item>
  24. <v-form-item :wrapper-col="{offset:6, span: 14 }">
  25. <v-button type="primary" style="margin-right:10px" @click.prevent="submitForm('ruleForm')">立即创建</v-button>
  26. <v-button type="ghost" @click.prevent="resetForm('ruleForm')">重置</v-button>
  27. </v-form-item>
  28. </v-form>
  29. </template>
  30. <script>
  31. export default {
  32. data: ()=> ({
  33. ruleForm: {
  34. name: '',
  35. region: '',
  36. date: '',
  37. delivery: false,
  38. type: [],
  39. resource: '',
  40. desc: ''
  41. },
  42. rules: {
  43. name: [{
  44. required: true,
  45. message: '请输入活动名称'
  46. }],
  47. region: [{
  48. required: true,
  49. message: '请选择活动区域'
  50. }],
  51. date: [{
  52. required: true,
  53. message: '请选择日期'
  54. }],
  55. type: [{
  56. type: 'array',
  57. required: true,
  58. message: '请至少选择一个活动性质'
  59. }],
  60. resource: [{
  61. required: true,
  62. message: '请选择活动资源'
  63. }],
  64. desc: [{
  65. required: true,
  66. message: '请填写活动形式'
  67. }]
  68. },
  69. checkboxOpt: [{
  70. label: '美食/餐厅线上活动',
  71. value: '1'
  72. },
  73. {
  74. label: '地推活动',
  75. value: '2'
  76. },
  77. {
  78. label: '线下主题活动',
  79. value: '3'
  80. },
  81. {
  82. label: '单纯品牌曝光',
  83. value: '4'
  84. }
  85. ],
  86. labelCol: {
  87. span: 6
  88. },
  89. wrapperCol: {
  90. span: 14
  91. }
  92. }),
  93. methods: {
  94. submitForm(formName) {
  95. this.$refs[formName].validate((valid) => {
  96. if (valid) {
  97. alert('submit!');
  98. } else {
  99. console.log('error submit!!');
  100. return false;
  101. }
  102. });
  103. },
  104. resetForm(formName) {
  105. this.$refs[formName].resetFields();
  106. }
  107. }
  108. }
  109. </script>

自定义校验规则

更加灵活的表单校验。

  1. <template>
  2. <v-form direction="horizontal" :model="customForm" :rules="customRules" ref="customRuleForm">
  3. <v-form-item label="密码" :label-col="labelCol" :wrapper-col="wrapperCol" prop="pass" has-feedback>
  4. <v-input type="password" size="large" v-model="customForm.pass"></v-input>
  5. </v-form-item>
  6. <v-form-item label="确认密码" :label-col="labelCol" :wrapper-col="wrapperCol" prop="checkPass" has-feedback>
  7. <v-input type="password" size="large" v-model="customForm.checkPass"></v-input>
  8. </v-form-item>
  9. <v-form-item label="年龄" :label-col="labelCol" :wrapper-col="wrapperCol" prop="age" has-feedback>
  10. <v-input size="large" v-model="customForm.age"></v-input>
  11. </v-form-item>
  12. <v-form-item :wrapper-col="{offset:6, span: 14 }">
  13. <v-button type="primary" style="margin-right:10px" @click.prevent="submitForm('customRuleForm')">提交</v-button>
  14. <v-button type="ghost" @click.prevent="resetForm('customRuleForm')">重置</v-button>
  15. </v-form-item>
  16. </v-form>
  17. </template>
  18. <script>
  19. export default {
  20. data() {
  21. var checkAge = (rule, value, callback) => {
  22. var age = parseInt(value, 10);
  23. setTimeout(() => {
  24. if (!Number.isInteger(age)) {
  25. callback(new Error('请输入数字值'));
  26. } else {
  27. if (age < 18) {
  28. callback(new Error('必须年满18岁'));
  29. } else {
  30. callback();
  31. }
  32. }
  33. }, 1000);
  34. };
  35. var validatePass = (rule, value, callback) => {
  36. if (value === '') {
  37. callback(new Error('请输入密码'));
  38. } else {
  39. if (this.customForm.checkPass !== '') {
  40. this.$refs.customRuleForm.validateField('checkPass');
  41. }
  42. callback();
  43. }
  44. };
  45. var validatePass2 = (rule, value, callback) => {
  46. if (value === '') {
  47. callback(new Error('请再次输入密码'));
  48. } else if (value !== this.customForm.pass) {
  49. callback(new Error('两次输入密码不一致!'));
  50. } else {
  51. callback();
  52. }
  53. };
  54. return {
  55. customForm: {
  56. pass: '',
  57. checkPass: '',
  58. age: ''
  59. },
  60. customRules: {
  61. pass: [{
  62. required: true,
  63. message: '请输入密码'
  64. },
  65. {
  66. validator: validatePass
  67. }
  68. ],
  69. checkPass: [{
  70. required: true,
  71. message: '请再次输入密码'
  72. },
  73. {
  74. validator: validatePass2
  75. }
  76. ],
  77. age: [{
  78. required: true,
  79. message: '请填写年龄'
  80. },
  81. {
  82. validator: checkAge
  83. }
  84. ]
  85. },
  86. labelCol: {
  87. span: 6
  88. },
  89. wrapperCol: {
  90. span: 14
  91. }
  92. }
  93. },
  94. methods: {
  95. submitForm(formName) {
  96. this.$refs[formName].validate((valid) => {
  97. if (valid) {
  98. alert('submit!');
  99. } else {
  100. console.log('error submit!!');
  101. return false;
  102. }
  103. });
  104. },
  105. resetForm(formName) {
  106. this.$refs[formName].resetFields();
  107. }
  108. }
  109. }
  110. </script>

动态增减表单项

除了在 Form 组件上一次性传递所有的验证规则外还可以在单个的表单域上传递属性的验证规则

  1. <template>
  2. <v-form direction="horizontal" :model="dynamicValidateForm" ref="dynamicValidateForm">
  3. <v-form-item label="邮箱" :label-col="labelCol" :wrapper-col="wrapperCol" prop="email"
  4. :rules="[
  5. { required: true, message: '请输入邮箱地址', trigger: 'blur' },
  6. { type: 'email', message: '请输入正确的邮箱地址', trigger: 'blur,change' }
  7. ]"
  8. >
  9. <v-input size="large" v-model="dynamicValidateForm.email"></v-input>
  10. </v-form-item>
  11. <v-form-item :label-col="labelCol" :wrapper-col="wrapperCol"
  12. v-for="(domain, index) in dynamicValidateForm.domains"
  13. :label="'域名' + index"
  14. :key="domain.key"
  15. :prop="'domains.' + index + '.value'"
  16. :rules="{
  17. required: true, message: '域名不能为空', trigger: 'blur'
  18. }"
  19. >
  20. <v-input size="large" v-model="domain.value" style="width:78%;margin-right:10px"></v-input><v-button @click.prevent="removeDomain(domain)">删除</v-button>
  21. </v-form-item>
  22. <v-form-item :wrapper-col="{offset:6, span: 14 }">
  23. <v-button type="primary" style="margin-right:10px" @click.prevent="submitForm('dynamicValidateForm')">提交</v-button>
  24. <v-button @click="addDomain">新增域名</v-button>
  25. <v-button @click="resetForm('dynamicValidateForm')">重置</v-button>
  26. </v-form-item>
  27. </v-form>
  28. </template>
  29. <script>
  30. export default {
  31. data() {
  32. return {
  33. dynamicValidateForm: {
  34. domains: [{
  35. value: ''
  36. }],
  37. email: ''
  38. },
  39. labelCol: {
  40. span: 6
  41. },
  42. wrapperCol: {
  43. span: 14
  44. }
  45. }
  46. },
  47. methods: {
  48. submitForm(formName) {
  49. this.$refs[formName].validate((valid) => {
  50. if (valid) {
  51. alert('submit!');
  52. } else {
  53. console.log('error submit!!');
  54. return false;
  55. }
  56. });
  57. },
  58. resetForm(formName) {
  59. this.$refs[formName].resetFields();
  60. },
  61. removeDomain(item) {
  62. var index = this.dynamicValidateForm.domains.indexOf(item)
  63. if (index !== -1) {
  64. this.dynamicValidateForm.domains.splice(index, 1)
  65. }
  66. },
  67. addDomain() {
  68. this.dynamicValidateForm.domains.push({
  69. value: '',
  70. key: Date.now()
  71. });
  72. }
  73. }
  74. }
  75. </script>

API

Form Props

参数说明类型默认值
model表单数据对象object-
rules表单验证规则object-
directionform 排列布局方式 inline、vertical或者horizontalstringinline
showMessage是否显示校验错误信息booleantrue

Form Methods

方法名说明参数返回值
validate对整个表单进行校验的方法callback(boolean)-
validateFieldvalidateFieldprop: string,callback: function(errorMessage: string)-
resetFields对整个表单进行重置,将所有字段值重置为空并移除校验结果--

Form Item Props

参数说明类型默认值
prop表单域 model 字段传入 Form 组件的 model 中的字段-
help提示信息,如不设置,则会根据校验规则自动生成string-
hasFeedback配合 validateStatus 属性使用,展示校验状态图标,建议只配合 Input 组件使用booleanfalse
validateStatus校验状态,如不设置,则会根据校验规则自动生成('success' 'warning' 'error' 'validating')string-
required是否必填,如不设置,则会根据校验规则自动生成booleanfalse
labellabel 标签的文本string-
labelCollabel 标签布局,通 v-col 组件,设置 span offset 值,如 {span: 3, offset: 12}object-
wrapperCol需要为输入控件设置布局样式时,使用该属性,用法同 labelColobject-
rules表单验证规则object-
showMessage是否显示校验错误信息booleantrue