Skip to content

Form

Composed of inputs, selects, radios, checkboxes and other controls, for collecting, validating, and submitting data.

Basic Usage

Basic form usage with form items such as inputs, selects, switches, radios, checkboxes etc.

<template>
  <div style="width: 500px">
    <b-form ref="form" :model="formObj" label-width="100px">
      <b-form-item label="Name">
        <b-input v-model="formObj.name" placeholder="输入Name"></b-input>
      </b-form-item>
      <b-form-item label="Age">
        <b-input-number v-model="formObj.age"></b-input-number>
      </b-form-item>
      <b-form-item label="Hometown">
        <b-select v-model="formObj.region" placeholder="Please selectHometown">
          <b-option label="Shanghai" value="shanghai"></b-option>
          <b-option label="Beijing" value="beijing"></b-option>
          <b-option label="Nanjing" value="nanjing"></b-option>
          <b-option label="Xuzhou" value="xuzhou"></b-option>
        </b-select>
      </b-form-item>
      <b-form-item label="Education">
        <b-radio-group v-model="formObj.edu">
          <b-radio label="High School"></b-radio>
          <b-radio label="College"></b-radio>
          <b-radio label="Bachelor"></b-radio>
          <b-radio label="Master"></b-radio>
        </b-radio-group>
      </b-form-item>
      <b-form-item label="Hobby">
        <b-checkbox-group v-model="formObj.hobby">
          <b-checkbox label="打游戏" name="hobby"></b-checkbox>
          <b-checkbox label="看电影" name="hobby"></b-checkbox>
          <b-checkbox label="打篮球/运动" name="hobby"></b-checkbox>
          <b-checkbox label="看书" name="hobby"></b-checkbox>
        </b-checkbox-group>
      </b-form-item>
      <b-form-item label="Address">
        <b-input v-model="formObj.address" type="textarea" placeholder="Please enterAddress..."></b-input>
      </b-form-item>
      <b-form-item>
        <b-button type="primary" @click="onSubmit">Submit</b-button>
        <b-button>Cancel</b-button>
      </b-form-item>
    </b-form>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'

const formObj = ref({
  name: '',
  age: null,
  region: '',
  city: '',
  edu: '',
  hobby: [],
  address: ''
})

function onSubmit() {
  console.log('submit!', formObj.value)
}
</script>

Inline Form

Use inline mode when there are few form items.

<template>
  <b-form ref="form" :model="formObj" inline class="demo-form-inline">
    <b-form-item label="Name">
      <b-input v-model="formObj.name" placeholder="输入Name"></b-input>
    </b-form-item>
    <b-form-item label="Hometown">
      <b-select v-model="formObj.region" placeholder="Please selectHometown">
        <b-option label="Shanghai" value="shanghai"></b-option>
        <b-option label="Beijing" value="beijing"></b-option>
        <b-option label="Nanjing" value="nanjing"></b-option>
        <b-option label="Xuzhou" value="xuzhou"></b-option>
      </b-select>
    </b-form-item>
    <b-form-item>
      <b-button type="primary" @click="onSubmit">Submit</b-button>
    </b-form-item>
  </b-form>
</template>

<script setup lang="ts">
import { ref } from 'vue'

const formObj = ref({
  name: '',
  region: ''
})

function onSubmit() {
  console.log('submit!', formObj.value)
}
</script>

Alignment and Size

Three label alignment options are available. Pure text labels need to be wrapped in a label tag.

Alignment
Size
Text Display
<template>
  <div>
    <b-space>
      Alignment
      <b-radio-group v-model="labelPosition" type="capsule">
        <b-radio label="left">Left</b-radio>
        <b-radio label="right">Right</b-radio>
        <b-radio label="top">Top</b-radio>
      </b-radio-group>
      Size
      <b-radio-group v-model="size" type="capsule">
        <b-radio label="large">large</b-radio>
        <b-radio label="default">default</b-radio>
        <b-radio label="small">small</b-radio>
        <b-radio label="mini">mini</b-radio>
      </b-radio-group>
      Text Display
      <b-switch v-model="onlyText"></b-switch>
    </b-space>
    <div style="width: 500px; margin-top: 20px">
      <b-form :label-position="labelPosition" label-width="100px" :model="formObj" :size="size">
        <b-form-item label="Name">
          <b-input v-if="!onlyText" v-model="formObj.name" placeholder="Enter Name"></b-input>
          <label v-else>{{ formObj.name }}</label>
        </b-form-item>
        <b-form-item label="Age">
          <b-input-number v-if="!onlyText" v-model="formObj.age"></b-input-number>
          <label v-else>{{ formObj.age }}</label>
        </b-form-item>
        <b-form-item label="Hometown">
          <b-select v-if="!onlyText" v-model="formObj.city" placeholder="Please selectHometown">
            <b-option label="Shanghai" value="shanghai"></b-option>
            <b-option label="Beijing" value="beijing"></b-option>
            <b-option label="Nanjing" value="nanjing"></b-option>
            <b-option label="Xuzhou" value="xuzhou"></b-option>
          </b-select>
          <label v-else>{{ formObj.city }}</label>
        </b-form-item>
        <b-form-item label="Education">
          <b-radio-group v-if="!onlyText" v-model="formObj.edu">
            <b-radio label="High School"></b-radio>
            <b-radio label="College"></b-radio>
            <b-radio label="Bachelor"></b-radio>
            <b-radio label="Master"></b-radio>
          </b-radio-group>
          <span v-else>{{ formObj.edu }}</span>
        </b-form-item>
        <b-form-item label="Hobby">
          <b-checkbox-group v-if="!onlyText" v-model="formObj.hobby">
            <b-checkbox label="打游戏" name="hobby"></b-checkbox>
            <b-checkbox label="看电影" name="hobby"></b-checkbox>
            <b-checkbox label="打篮球/运动" name="hobby"></b-checkbox>
            <b-checkbox label="看书" name="hobby"></b-checkbox>
          </b-checkbox-group>
          <span v-else>{{ formObj.hobby }}</span>
        </b-form-item>
        <b-form-item label="Address">
          <b-input
            v-if="!onlyText"
            v-model="formObj.address"
            type="textarea"
            placeholder="Please enterAddress..."
          ></b-input>
          <span v-else>{{ formObj.address }}</span>
        </b-form-item>
        <!-- <b-form-item label="进度">
        <b-slider></b-slider>
      </b-form-item>
      <b-form-item label="color">
        <b-color-picker></b-color-picker>
      </b-form-item>
      <b-form-item label="rate">
        <b-rate></b-rate>
      </b-form-item>
      <b-form-item label="Day期选择器">
        <b-date-picker></b-date-picker>
      </b-form-item>
      <b-form-item label="time picker">
        <b-time-picker></b-time-picker>
      </b-form-item>
      <b-form-item label="switch">
        <b-switch></b-switch>
      </b-form-item> -->
        <b-form-item v-if="!onlyText">
          <b-button type="primary">Submit</b-button>
          <b-button>Cancel</b-button>
        </b-form-item>
      </b-form>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'

const labelPosition = ref('right')
const size = ref('default')
const onlyText = ref(false)

const formObj = ref({
  name: 'John Doe',
  age: 18,
  city: 'xuzhou',
  edu: 'High School',
  hobby: ['打游戏', '看电影'],
  address: 'XuzhouCityGulou District'
})
</script>

Without Label Display

<template>
  <div style="width: 500px">
    <b-form :model="formObj">
      <b-form-item>
        <b-input v-model="formObj.username" placeholder="输入Username"></b-input>
      </b-form-item>
      <b-form-item>
        <b-input v-model="formObj.password" placeholder="输入Username" type="password"></b-input>
      </b-form-item>
      <b-form-item>
        <b-button type="primary" style="width: 100%">Login</b-button>
      </b-form-item>
    </b-form>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'

const formObj = ref({
  username: '',
  password: ''
})
</script>

Form Validation

Provides basic validation rules. See async-validator for reference.

<template>
  <div style="width: 500px">
    <b-form ref="ruleForm" :model="formObj" status-icon label-width="100px" :rules="ruleValidate">
      <b-form-item prop="name" label="Name">
        <b-input v-model="formObj.name" placeholder="Username"></b-input>
      </b-form-item>
      <b-form-item prop="mail" label="Email">
        <b-input v-model="formObj.mail" placeholder="Email" clearable></b-input>
      </b-form-item>
      <b-row>
        <b-col :span="12">
          <b-form-item prop="age" label="Age">
            <b-input-number v-model="formObj.age" style="width: 100%"></b-input-number>
          </b-form-item>
        </b-col>
        <b-col :span="12">
          <b-form-item label="Hometown" prop="region">
            <b-select v-model="formObj.region" placeholder="Please selectHometown" clearable>
              <b-option label="Shanghai" value="shanghai"></b-option>
              <b-option label="Beijing" value="beijing"></b-option>
              <b-option label="Nanjing" value="nanjing"></b-option>
              <b-option label="Xuzhou" value="xuzhou"></b-option>
            </b-select>
          </b-form-item>
        </b-col>
      </b-row>
      <b-form-item label="Birthday" prop="birthday">
        <b-date-picker
          v-model="formObj.birthday"
          type="date"
          placeholder="Birthday"
        ></b-date-picker>
      </b-form-item>
      <b-form-item label="Hobby" prop="hobby">
        <b-checkbox-group v-model="formObj.hobby">
          <b-checkbox label="打游戏" name="hobby"></b-checkbox>
          <b-checkbox label="看电影" name="hobby"></b-checkbox>
          <b-checkbox label="打篮球/运动" name="hobby"></b-checkbox>
          <b-checkbox label="看书" name="hobby"></b-checkbox>
        </b-checkbox-group>
      </b-form-item>
      <b-form-item label="Gender" prop="sex">
        <b-radio-group v-model="formObj.sex">
          <b-radio label="Male" value="male"></b-radio>
          <b-radio label="Female" value="female"></b-radio>
        </b-radio-group>
      </b-form-item>
      <b-form-item label="Status" prop="status">
        <b-switch v-model="formObj.status" true-value="enable" false-value="disable" size="large">
          <template #open><span>Enable</span></template>
          <template #close><span>Disabled</span></template>
        </b-switch>
      </b-form-item>
      <b-form-item>
        <b-button type="primary" @click="submitForm">Submit</b-button>
        <b-button @click="resetForm">Reset</b-button>
      </b-form-item>
    </b-form>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'

const ruleValidate = {
  name: [{ required: true, message: 'UsernameCannot be empty', trigger: 'blur' }],
  region: [{ required: true, message: 'HometownCannot be empty', trigger: 'change' }],
  age: [
    { required: true, type: 'number', message: 'Age cannot be empty', trigger: 'change' },
    { type: 'number', min: 18, trigger: 'change', message: 'Age must be 18 or above' }
  ],
  hobby: [{ type: 'array', required: true, message: 'Please select at least one hobby', trigger: 'change' }],
  sex: [{ required: true, message: 'Gender is required', trigger: 'change' }],
  birthday: [{ required: true, type: 'date', message: 'Birthday is required', trigger: 'blur' }],
  mail: [
    { required: true, message: 'EmailCannot be empty', trigger: 'blur' },
    { type: 'email', message: 'EmailInvalid format', trigger: 'blur' }
  ]
}

const ruleForm = ref(null)

const formObj = ref({
  name: '',
  age: null,
  mail: '',
  region: '',
  hobby: [],
  sex: '',
  status: 'disable',
  birthday: ''
})

function submitForm() {
  ruleForm.value?.validate(valid => {
    if (valid) {
      alert('submit!')
    } else {
      console.log('error submit!!')
      return false
    }
  })
}
function resetForm() {
  ruleForm.value?.resetFields()
}
</script>

Custom Validation Rules

Custom validation functions can be used for more complex validation logic.

<template>
  <div style="width: 500px">
    <b-form
      ref="ruleFormRef"
      :model="ruleForm"
      status-icon
      :rules="rules"
      label-width="100px"
      class="demo-ruleForm"
    >
      <b-form-item label="Password" prop="pass">
        <b-input v-model="ruleForm.pass" type="password" autocomplete="off"></b-input>
      </b-form-item>
      <b-form-item label="ConfirmPassword" prop="checkPass">
        <b-input v-model="ruleForm.checkPass" type="password" autocomplete="off"></b-input>
      </b-form-item>
      <b-form-item label="Age" prop="age">
        <b-input v-model.number="ruleForm.age" type="number"></b-input>
      </b-form-item>
      <b-form-item>
        <b-button type="primary" @click="submitForm">Submit</b-button>
        <b-button @click="resetForm">Reset</b-button>
      </b-form-item>
    </b-form>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'

const checkAge = (rule, value, callback) => {
  if (!value) {
    return callback(new Error('AgeCannot be empty'))
  }
  setTimeout(() => {
    if (!Number.isInteger(value)) {
      callback(new Error('Please enter a numeric value'))
    } else {
      if (value < 18) {
        callback(new Error('Must be at least 18 years old'))
      } else {
        callback()
      }
    }
  }, 1000)
}
const validatePass = (rule, value, callback) => {
  if (value === '') {
    callback(new Error('Please enterPassword'))
  } else {
    if (ruleForm.value.checkPass !== '') {
      ruleFormRef.value?.validateField('checkPass')
    }
    callback()
  }
}
const validatePass2 = (rule, value, callback) => {
  if (value === '') {
    callback(new Error('Please enter the password again'))
  } else if (value !== ruleForm.value.pass) {
    callback(new Error('The two passwords do not match!'))
  } else {
    callback()
  }
}

const ruleFormRef = ref(null)

const rules = ref({
  pass: [{ validator: validatePass, trigger: 'blur' }],
  checkPass: [{ validator: validatePass2, trigger: 'blur' }],
  age: [{ validator: checkAge, trigger: 'blur' }]
})

const ruleForm = ref({
  pass: '',
  checkPass: '',
  age: ''
})

function submitForm() {
  ruleFormRef.value?.validate(valid => {
    if (valid) {
      alert('submit!')
    } else {
      console.log('error submit!!')
      return false
    }
  })
}
function resetForm() {
  ruleFormRef.value?.resetFields()
}
</script>

Dynamic Validation

Validation rules can be configured dynamically.

<template>
  <div style="width: 500px">
    <b-form ref="formRef" :model="dynamicValidateForm" label-width="100px" class="demo-dynamic">
      <b-form-item
        v-for="(domain, index) in dynamicValidateForm.domains"
        :key="domain.key"
        :label="'Domain' + index"
        :prop="'domains.' + index + '.value'"
        :rules="{
          required: true,
          message: 'DomainCannot be empty',
          trigger: 'blur'
        }"
      >
        <div flex="box:last">
          <b-input v-model="domain.value"></b-input>
          <b-button @click="removeDomain(domain)">Delete</b-button>
        </div>
      </b-form-item>
      <b-form-item>
        <b-button type="primary" @click="submitForm">Submit</b-button>
        <b-button @click="addDomain">Add Domain</b-button>
        <b-button @click="resetForm">Reset</b-button>
      </b-form-item>
    </b-form>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'

const dynamicValidateForm = ref({
  domains: [
    {
      value: ''
    }
  ]
})
const formRef = ref(null)

function submitForm() {
  formRef.value?.validate(valid => {
    if (valid) {
      alert('submit!')
    } else {
      console.log('error submit!!')
      return false
    }
  })
}
function resetForm() {
  formRef.value?.resetFields()
}
function removeDomain(item) {
  const index = dynamicValidateForm.value.domains.indexOf(item)
  if (index !== -1) {
    dynamicValidateForm.value.domains.splice(index, 1)
  }
}
function addDomain() {
  dynamicValidateForm.value.domains.push({
    value: '',
    key: Date.now()
  })
}
</script>

Form Props

ParameterDescriptionTypeOptionsDefault
modelForm data objectobject
rulesForm validation rulesobject
inlineInline form modebooleanfalse
label-positionLabel position. When set to left or right, label-width must also be set.right / left / topright
label-widthWidth of form item labels, e.g. '50px'. Direct form-item children of Form inherit this value. Supports auto.
label-suffixSuffix for form item labelsstring
hide-required-asteriskHide the red asterisk next to required field labels*booleanfalse
show-messageShow validation error messagebooleantrue
inline-messageShow validation messages inline. The right side must reserve space for the validation message.booleanfalse
status-iconWhether to show validation result icon in the inputbooleanfalse
validate (Date)-on-rule-changeWhether to trigger validation immediately after rules changebooleantrue
sizeControls the size of components within this formstringlarge,default,small,mini
disabledDisables all components within the form. If set to true, the disabled property on individual components inside the form will no longer take effectbooleanfalse

Form Methods

Method NameDescriptionReturn Value
validateMethod to validate the entire form. The parameter is a callback function that is invoked after validation completes, receiving two parameters: whether validation succeeded and the fields that failed validation. If no callback is provided, it returns a promiseFunction(callback: Function(boolean, object))
validateFieldMethod to validate specific form fieldsFunction(props: array / string, callback: Function(errorMessage: string))
resetFieldsResets the entire form, restoring all field values to their initial values and removing validation results
clearValidateRemoves validation results for form items. Pass the prop property of the form item(s) or an array of props; if not passed, removes validation results for the entire formFunction(props: array / string)

Form Events

Method NameDescriptionReturn Value
validateTriggers after any form item is validatedThe prop value of the validated form item, whether validation passed, and the error message (if any)

FormItem Props

ParameterDescriptionTypeOptionsDefault
propForm item model field; required when using validate or resetFields methodsstringField in the model passed to the Form component
labelLabel textstring
label-widthWidth of form item label, e.g. '80px'. Supports auto.string
requiredWhether it is required. If not set, it will be auto-generated based on validation rulesbooleanfalse
rulesForm validation rulesobject
errorForm item validation error message. Setting this value will change the form validation state to error and display the error messagestring
show-messageShow validation error messagebooleantrue
inline-messageDisplay validation messages inlinebooleanfalse
sizeControls the size of components under this form itemstringlarge,default,small,mini

FormItem Slot

NameDescription
defaultDefaultContent
labelLabel text content

FormItem Scoped Slot

NameDescription
errorCustom display of form validation info, parameter is

FormItem Methods

NameDescription
resetFieldResets this form item, restoring its value to the initial value and removing validation results
clearValidateRemoves the validation result for this form item