Vue3 表单(详细教程)

Vue3 表单:从零开始掌握前端数据输入的艺术

在现代 Web 开发中,表单是用户与系统交互最核心的桥梁。无论是注册登录、信息填写,还是复杂的多步骤向导,Vue3 表单都承担着数据收集、验证和响应的关键角色。对于初学者来说,表单可能只是“输入框加按钮”的简单组合;但对于中级开发者而言,如何高效管理状态、实现双向绑定、处理复杂验证逻辑,才是真正的挑战。

Vue 3 引入了 Composition API 和 ref / reactive 等新特性,让表单开发变得更加灵活和可维护。本文将带你一步步掌握 Vue3 表单的核心原理与实战技巧,从基础绑定到高级验证,涵盖真实项目中常见场景。


基础表单绑定:v-model 的工作原理

在 Vue 3 中,v-model 是实现表单元素双向绑定的核心指令。它本质上是一个语法糖,自动帮你完成 :value@input 事件的绑定。

<template>
  <div>
    <!-- 用户名输入框 -->
    <input 
      v-model="username" 
      placeholder="请输入用户名" 
      type="text"
    />
    <!-- 显示当前输入值 -->
    <p>当前用户名:{{ username }}</p>
  </div>
</template>

<script setup>
// 使用 setup 语法糖,定义响应式数据
import { ref } from 'vue'

// 声明一个响应式变量 username,初始值为空字符串
const username = ref('')

// 当用户输入时,username 会自动更新;
// 当 username 变化时,视图也会实时刷新
</script>

注释说明

  • ref('') 创建一个响应式引用,包裹原始值(字符串、数字等)
  • v-model 在底层等价于 :value="username" @input="username = $event.target.value"
  • 该机制确保了“数据驱动视图,视图反馈数据”的闭环

这种双向绑定就像你家的智能门锁:你转动把手(输入),门锁自动记录;当你通过手机 App 查看状态时,门锁的开关状态也实时同步。


多种表单元素的绑定实践

Vue3 支持几乎所有原生表单元素的绑定,包括文本框、复选框、单选按钮、下拉菜单等。掌握它们的绑定方式,是构建复杂表单的基础。

文本框与文本域

<template>
  <div>
    <label>用户名:</label>
    <input v-model="form.username" type="text" placeholder="请输入用户名" />

    <label>简介:</label>
    <textarea v-model="form.bio" rows="4" placeholder="请简要描述自己"></textarea>
  </div>
</template>

<script setup>
import { reactive } from 'vue'

// 使用 reactive 创建响应式对象,适合管理多个表单项
const form = reactive({
  username: '',
  bio: ''
})
</script>

注释说明

  • reactive() 用于创建一个响应式对象,适合管理一组相关数据
  • 比起 refreactive 更适合表单数据结构,避免“变量爆炸”
  • textarearows 属性控制行数,v-model 同样支持双向绑定

复选框与单选按钮

<template>
  <div>
    <label>
      <input type="checkbox" v-model="form.hobbies" value="reading" />
      阅读
    </label>

    <label>
      <input type="checkbox" v-model="form.hobbies" value="coding" />
      编程
    </label>

    <label>
      <input type="checkbox" v-model="form.hobbies" value="travel" />
      旅行
    </label>

    <p>兴趣爱好:{{ form.hobbies.join(', ') }}</p>
  </div>
</template>

<script setup>
import { reactive } from 'vue'

const form = reactive({
  hobbies: [] // 复选框绑定数组,选中时添加 value,未选中则不包含
})
</script>

注释说明

  • 多个 checkbox 绑定到同一个数组变量,Vue 会自动维护选中状态
  • value 属性定义每个选项的值,最终结果是数组
  • join(', ') 用于格式化输出,提升可读性

下拉选择框

<template>
  <div>
    <label>城市选择:</label>
    <select v-model="form.city">
      <option value="">请选择城市</option>
      <option value="beijing">北京</option>
      <option value="shanghai">上海</option>
      <option value="guangzhou">广州</option>
    </select>

    <p>选择的城市:{{ form.city }}</p>
  </div>
</template>

<script setup>
import { reactive } from 'vue'

const form = reactive({
  city: ''
})
</script>

注释说明

  • selectv-model 绑定的是 optionvalue
  • value="" 作为默认空选项,避免无选择状态
  • 与 checkbox 不同,select 通常绑定单个值,适合单选场景

表单数据结构管理:使用 reactive vs ref

在构建中大型表单时,选择合适的响应式数据结构至关重要。reactiveref 各有优势,合理搭配才能写出清晰、易维护的代码。

特性 reactive ref
适用场景 多个字段的复杂对象 单个值或简单变量
响应式方式 对象整体响应 包裹值的引用响应
读取值 form.username form.username.value
优势 结构清晰,适合表单对象 灵活,可直接传递
<template>
  <div>
    <input v-model="form.name" placeholder="姓名" />
    <input v-model="form.age" type="number" placeholder="年龄" />
    <button @click="submitForm">提交</button>
  </div>
</template>

<script setup>
import { reactive } from 'vue'

// 推荐:使用 reactive 管理表单数据
const form = reactive({
  name: '',
  age: null
})

// 提交表单方法
const submitForm = () => {
  console.log('提交数据:', form)
  // 这里可以发送到后端 API
}
</script>

注释说明

  • reactive 更适合表单对象,避免频繁写 .value
  • 当表单字段较多时,reactive 可读性远高于一堆 ref
  • 若需传递给子组件,reactive 对象也可被解构使用(需注意响应性丢失问题)

表单验证:从基础校验到自定义规则

表单验证是保障数据质量的关键环节。Vue3 本身不提供验证库,但我们可以结合 v-model 和逻辑判断轻松实现。

基础非空验证

<template>
  <div>
    <input v-model="form.email" placeholder="请输入邮箱" />
    <!-- 显示错误提示 -->
    <p v-if="!form.email && isSubmitted" class="error">邮箱不能为空</p>

    <button @click="submitForm">提交</button>
  </div>
</template>

<script setup>
import { reactive } from 'vue'

const form = reactive({
  email: ''
})

// 标记是否已提交,用于控制错误提示显示时机
const isSubmitted = ref(false)

const submitForm = () => {
  isSubmitted.value = true

  if (!form.email) {
    console.log('请填写邮箱')
    return
  }

  // 验证通过,提交数据
  console.log('表单提交成功:', form)
}
</script>

注释说明

  • isSubmitted 控制错误提示的触发时机,避免用户未操作就看到报错
  • 仅在点击提交后才检查,符合用户体验逻辑
  • 可扩展为正则验证邮箱格式(如 /^\S+@\S+\.\S+$/

自定义验证函数

// 工具函数:邮箱格式验证
const isValidEmail = (email) => {
  const regex = /^\S+@\S+\.\S+$/
  return regex.test(email)
}

// 在提交时调用
const submitForm = () => {
  isSubmitted.value = true

  if (!form.email) {
    return
  }

  if (!isValidEmail(form.email)) {
    console.log('邮箱格式不正确')
    return
  }

  console.log('提交成功')
}

注释说明

  • 将验证逻辑抽离为函数,提高复用性和可测试性
  • 支持后续扩展更多规则(如密码强度、手机号校验)

实战案例:用户注册表单

我们来整合前面所有知识点,构建一个完整的用户注册表单。

<template>
  <form @submit.prevent="submitForm" class="register-form">
    <h3>用户注册</h3>

    <div>
      <label>用户名:</label>
      <input v-model="form.username" placeholder="至少 3 个字符" />
      <p v-if="errors.username" class="error">{{ errors.username }}</p>
    </div>

    <div>
      <label>邮箱:</label>
      <input v-model="form.email" placeholder="example@domain.com" />
      <p v-if="errors.email" class="error">{{ errors.email }}</p>
    </div>

    <div>
      <label>密码:</label>
      <input v-model="form.password" type="password" placeholder="至少 6 位" />
      <p v-if="errors.password" class="error">{{ errors.password }}</p>
    </div>

    <button type="submit">注册</button>
  </form>
</template>

<script setup>
import { reactive } from 'vue'

// 表单数据
const form = reactive({
  username: '',
  email: '',
  password: ''
})

// 错误信息对象
const errors = reactive({
  username: '',
  email: '',
  password: ''
})

// 提交处理
const submitForm = () => {
  // 清空旧错误
  Object.keys(errors).forEach(key => {
    errors[key] = ''
  })

  // 校验逻辑
  if (!form.username || form.username.length < 3) {
    errors.username = '用户名至少 3 个字符'
  }

  if (!form.email || !/^\S+@\S+\.\S+$/.test(form.email)) {
    errors.email = '请输入有效的邮箱地址'
  }

  if (!form.password || form.password.length < 6) {
    errors.password = '密码至少 6 位'
  }

  // 所有验证通过
  if (!errors.username && !errors.email && !errors.password) {
    console.log('注册成功', form)
    // 可调用 API 提交
  }
}
</script>

<style scoped>
.register-form {
  max-width: 400px;
  margin: 20px auto;
  padding: 20px;
  border: 1px solid #ddd;
  border-radius: 8px;
}

.error {
  color: red;
  font-size: 14px;
  margin-top: 4px;
}

input {
  width: 100%;
  padding: 8px;
  margin-top: 4px;
  border: 1px solid #ccc;
  border-radius: 4px;
}

button {
  margin-top: 16px;
  padding: 10px 20px;
  background: #007bff;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}
</style>

注释说明

  • @submit.prevent 阻止默认提交行为,避免页面刷新
  • 使用 reactive 管理表单和错误信息,结构清晰
  • 每个字段独立校验,错误信息动态显示
  • 最终实现“输入 → 校验 → 提交”完整流程

总结:Vue3 表单的核心要点

Vue3 表单不仅是数据输入的工具,更是状态管理与用户体验的集中体现。通过 v-model 实现双向绑定,结合 refreactive 管理数据结构,再配合自定义校验逻辑,我们可以构建出既美观又健壮的表单系统。

从简单文本输入到复杂的多步骤注册,Vue3 提供了足够的灵活性与扩展性。关键在于:将表单视为一个状态机,每一项输入都影响其状态,而状态变化应驱动视图反馈

掌握这些技巧后,你不仅能写出正确的表单,更能写出“可读、可维护、可扩展”的高质量代码。无论你是初学者还是中级开发者,只要坚持实践,一定能驾驭好 Vue3 表单这一核心技能。