源本科技 | 码上会

Vue3 表单输入绑定

2026/04/22
36
0

引言

Vue 3 中的表单输入绑定通过 v-model 指令实现双向数据绑定,可将 input、textarea、select 等表单元素的取值与组件的响应式状态关联。v-model 内置专属修饰符,支持自定义绑定值,是 Vue 开发中处理表单的核心语法,适配所有原生表单元素。


绑定基础

基于 Vue 3 <script setup> 组合式 API,v-model 配合 ref 声明的响应式数据,即可实现表单值与数据的双向同步,覆盖所有原生表单元素场景。

单行文本输入

v-model 监听 input 事件,实时同步单行输入框的值与响应式数据。

<script setup>
import { ref } from 'vue'
// 声明响应式数据
const message = ref('')
</script>

<template>
  <p>Message is: {{ message }}</p>
  <input v-model="message" placeholder="edit me" />
</template>

多行文本输入

v-model 适用于 textarea 多行文本框,同样监听 input 事件实时同步。 核心规范textarea 不支持插值表达式,必须使用 v-model 绑定数据。

<script setup>
import { ref } from 'vue'
const message = ref('')
</script>

<template>
  <span>Multiline message is:</span>
  <p style="white-space: pre-line;">{{ message }}</p>
  <textarea v-model="message" placeholder="add multiple lines"></textarea>

  <!-- 错误写法:插值表达式在 textarea 中无效 -->
  <!-- <textarea>{{ message }}</textarea> -->
</template>

复选框

分为单个复选框(绑定布尔值)和多个复选框(绑定数组)两种场景:

<script setup>
import { ref } from 'vue'
// 单个复选框:布尔值
const checked = ref(false)
// 多个复选框:数组存储选中的 value
const checkedNames = ref([])
</script>

<template>
  <!-- 单个复选框 -->
  <div>
    <input type="checkbox" id="checkbox" v-model="checked" />
    <label for="checkbox">{{ checked }}</label>
  </div>

  <!-- 多个复选框 -->
  <div>Checked names: {{ checkedNames }}</div>
  <input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
  <label for="jack">Jack</label>
  <input type="checkbox" id="john" value="John" v-model="checkedNames">
  <label for="john">John</label>
  <input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
  <label for="mike">Mike</label>
</template>

单选按钮

一组单选按钮绑定同一个响应式数据,选中后自动赋值为对应 value

<script setup>
import { ref } from 'vue'
const picked = ref('')
</script>

<template>
  <div>Picked: {{ picked }}</div>
  <input type="radio" id="one" value="One" v-model="picked" />
  <label for="one">One</label>
  <input type="radio" id="two" value="Two" v-model="picked" />
  <label for="two">Two</label>
</template>

选择器

单选选择器通过 v-model 监听 change 事件同步选中值。 兼容提示:若初始值无匹配选项,select 会渲染为未选中状态,iOS 设备将无法选择第一项,建议添加空值禁用选项。

<script setup>
import { ref } from 'vue'
const selected = ref('')
</script>

<template>
  <div>Selected: {{ selected }}</div>
  <select v-model="selected">
    <option disabled value="">Please select one</option>
    <option>A</option>
    <option>B</option>
    <option>C</option>
  </select>
</template>

动态渲染选择器

通过 v-for 循环渲染动态选项,适配接口返回的选择列表:

<script setup>
import { ref } from 'vue'
const selected = ref('A')
// 动态选项数据
const options = ref([
  { text: 'One', value: 'A' },
  { text: 'Two', value: 'B' },
  { text: 'Three', value: 'C' }
])
</script>

<template>
  <select v-model="selected">
    <option v-for="option in options" :key="option.value" :value="option.value">
      {{ option.text }}
    </option>
  </select>
  <div>Selected: {{ selected }}</div>
</template>

自定义值绑定

原生表单元素的 value 默认为字符串 / 布尔值,通过 Vue 专属属性可自定义绑定值,支持动态数据、对象等复杂类型。

复选框自定义值

使用 Vue 专属属性 true-value / false-value,自定义复选框选中 / 取消的取值,支持动态绑定:

<script setup>
import { ref } from 'vue'
const toggle = ref('no')
// 动态自定义值
const dynamicTrueValue = ref('开启')
const dynamicFalseValue = ref('关闭')
</script>

<template>
  <!-- 静态自定义值 -->
  <input
    type="checkbox"
    v-model="toggle"
    true-value="yes"
    false-value="no"
  />
  <label>静态值:{{ toggle }}</label>

  <!-- 动态自定义值 -->
  <input
    type="checkbox"
    v-model="toggle"
    :true-value="dynamicTrueValue"
    :false-value="dynamicFalseValue"
  />
  <label>动态值:{{ toggle }}</label>
</template>

单选按钮动态值

通过 v-bind 绑定动态变量,选中后自动赋值为变量的值:

<script setup>
import { ref } from 'vue'
const pick = ref('')
const first = ref('选项 1')
const second = ref('选项 2')
</script>

<template>
  <input type="radio" v-model="pick" :value="first" />
  <label>{{ first }}</label>
  <input type="radio" v-model="pick" :value="second" />
  <label>{{ second }}</label>
  <div>选中值:{{ pick }}</div>
</template>

选择器对象值绑定

v-model 支持绑定非字符串类型(对象、数字等),直接赋值复杂数据:

<script setup>
import { ref } from 'vue'
const selected = ref(null)
</script>

<template>
  <select v-model="selected">
    <option :value="{ id: 1, label: '选项 1' }">选项 1</option>
    <option :value="{ id: 2, label: '选项 2' }">选项 2</option>
  </select>
  <div>选中对象:{{ selected }}</div>
</template>

v-model 修饰符

v-model 提供 3 个核心修饰符,优化输入行为,适配不同表单场景。

.lazy

默认 v-modelinput 事件实时更新数据;添加 .lazy 后,仅在change 事件(失去焦点 / 回车)时同步数据,减少不必要的渲染。

<!-- 失去焦点后更新数据,而非实时更新 -->
<input v-model.lazy="msg" />

.number

自动将输入内容转换为数字类型,无法通过 parseFloat() 转换时返回原始值;输入框设置 type="number" 时,该修饰符自动生效

<script setup>
import { ref } from 'vue'
const age = ref(0)
</script>

<template>
  <input type="number" v-model.number="age" />
  <p>年龄:{{ age }} | 数据类型:{{ typeof age }}</p>
</template>

.trim

自动去除用户输入内容首尾的空格,不处理中间空格,规范表单输入格式:

<input v-model.trim="msg" />

拓展知识

v-model 底层原理

Vue 3 中 v-model 是语法糖,等价于绑定属性 + 监听事件:

<input v-model="message" />
<!-- 等价于 -->
<input :model-value="message" @update:model-value="message = $event" />

多选选择器

select 标签添加 multiple 属性,v-model 绑定数组即可实现多选:

<script setup>
import { ref } from 'vue'
const multiSelected = ref([])
</script>

<template>
  <select v-model="multiSelected" multiple>
    <option>A</option>
    <option>B</option>
    <option>C</option>
  </select>
  <div>多选结果:{{ multiSelected }}</div>
</template>

响应式数据规范

所有表单绑定的数据,必须使用 ref 声明(基础数据类型),才能保证双向绑定生效。

总结

  1. 核心用法:v-model 配合 ref 响应式数据,适配所有原生表单元素,<script setup> 是 Vue 3 标准写法;

  2. 进阶能力:支持自定义值绑定(对象、动态值)、多选场景,覆盖复杂业务需求;

  3. 修饰符:.lazy(延迟更新)、.number(数字转换)、.trim(去空格)是表单开发常用优化手段;

  4. 底层逻辑:v-model 是语法糖,本质是属性绑定 + 事件监听。