v-model 入门教程

一、核心概念

v-model 是 Vue.js 中实现双向数据绑定 的指令,主要用于表单输入元素或自定义组件中。它本质上是语法糖,将 v-bind(单向绑定)和 v-on(事件监听)结合使用。

1.1 基本原理

  • 单向绑定v-bind:value="message" 将数据从组件传递到 DOM。

  • 事件监听v-on:input="message = $event.target.value" 将 DOM 的变化同步回数据。

  • v-model 的等价写法

    html 复制代码
    <input v-model="message">
    <!-- 等价于 -->
    <input :value="message" @input="message = $event.target.value">

二、基础用法

2.1 绑定到表单输入

文本输入
html 复制代码
<template>
  <input v-model="message" placeholder="输入内容">
  <p>输入的内容:{{ message }}</p>
</template>

<script>
export default {
  data() {
    return {
      message: ''
    }
  }
}
</script>
多行文本(textarea)
html 复制代码
<textarea v-model="description"></textarea>
复选框(Checkbox)
  • 单个复选框 (绑定布尔值):

    html 复制代码
    <input type="checkbox" v-model="isChecked">
    <label>{{ isChecked ? '已选中' : '未选中' }}</label>
  • 多个复选框 (绑定数组):

    html 复制代码
    <input type="checkbox" v-model="hobbies" value="读书">
    <input type="checkbox" v-model="hobbies" value="运动">
    <input type="checkbox" v-model="hobbies" value="音乐">
    <p>爱好:{{ hobbies.join(', ') }}</p>
单选按钮(Radio)
html 复制代码
<input type="radio" v-model="gender" value="男">
<input type="radio" v-model="gender" value="女">
<p>性别:{{ gender }}</p>
选择框(Select)
  • 单选

    html 复制代码
    <select v-model="selectedFruit">
      <option value="苹果">苹果</option>
      <option value="香蕉">香蕉</option>
    </select>
  • 多选 (绑定数组):

    html 复制代码
    <select v-model="selectedFruits" multiple>
      <option value="苹果">苹果</option>
      <option value="香蕉">香蕉</option>
    </select>

三、高级用法

3.1 修饰符(Modifiers)

Vue 提供了多个修饰符来简化常见操作:

.lazy
  • 默认在 input 事件时同步数据,使用 .lazy 修饰符改为在 change 事件后同步:

    html 复制代码
    <input v-model.lazy="message">
.number
  • 自动将输入值转换为数字类型:

    html 复制代码
    <input v-model.number="age">
.trim
  • 自动过滤输入的首尾空格:

    html 复制代码
    <input v-model.trim="username">

3.2 自定义组件中的 v-model

在自定义组件中使用 v-model 时,需要明确组件如何接收和触发更新。

Vue 2 的用法
  • 组件内部通过 value prop 接收数据,通过 input 事件触发更新:

    html 复制代码
    <!-- 父组件 -->
    <custom-input v-model="searchText"></custom-input>
    html 复制代码
    <!-- 子组件 CustomInput.vue -->
    <template>
      <input :value="value" @input="$emit('input', $event.target.value)">
    </template>
    <script>
    export default {
      props: ['value']
    }
    </script>
Vue 3 的用法
  • Vue 3 支持多个 v-model 绑定,且默认使用 modelValue 作为 prop,update:modelValue 作为事件:

    html 复制代码
    <!-- 父组件 -->
    <custom-input v-model="searchText"></custom-input>
    html 复制代码
    <!-- 子组件 CustomInput.vue -->
    <template>
      <input :value="modelValue" @input="$emit('update:modelValue', $event.target.value)">
    </template>
    <script>
    export default {
      props: ['modelValue']
    }
    </script>
多个 v-model 绑定(Vue 3)
html 复制代码
<!-- 父组件 -->
<custom-user v-model:name="userName" v-model:age="userAge"></custom-user>
html 复制代码
<!-- 子组件 CustomUser.vue -->
<template>
  <input :value="name" @input="$emit('update:name', $event.target.value)">
  <input :value="age" @input="$emit('update:age', $event.target.value)">
</template>
<script>
export default {
  props: ['name', 'age']
}
</script>

四、常见问题

4.1 为什么数据未同步?

  • 原因 :未正确声明 v-model 的 prop 或未触发事件。
  • 解决方案
    • 检查子组件是否通过 props 接收数据。
    • 确保通过 $emit 触发 update:modelValue 事件(Vue 3)或 input 事件(Vue 2)。

4.2 如何绑定非表单元素?

  • 场景 :需要手动控制 v-model 的更新逻辑。

  • 解决方案 :使用计算属性或手动监听事件:

    html 复制代码
    <template>
      <div @click="handleClick">{{ customValue }}</div>
    </template>
    <script>
    export default {
      props: ['modelValue'],
      methods: {
        handleClick() {
          this.$emit('update:modelValue', '点击后的值')
        }
      }
    }
    </script>

五、最佳实践

  1. 优先使用原生表单元素:v-model 在表单元素上的表现最直观。
  2. 自定义组件时明确约定 :通过 props$emit 定义清晰的接口。
  3. 合理使用修饰符:避免手动处理类型转换或空格过滤。
  4. Vue 2 与 Vue 3 的差异 :注意 Vue 3 中 v-model 的默认 prop 和事件名称变化。

六、总结

v-model 是 Vue.js 中实现双向数据绑定的核心工具,通过简单的语法糖大幅简化了表单处理的逻辑。无论是绑定原生表单元素还是自定义组件,掌握 v-model 的用法都能显著提升开发效率。

相关推荐
xier1234567 分钟前
高性能和高灵活度的react表格组件
前端
曦曜2928 分钟前
富文本编辑器
javascript
你打不到我呢9 分钟前
nestjs入门:上手数据库与prisma
前端
多啦C梦a10 分钟前
React 实战:从 setInterval 到 useInterval,一次搞懂定时器 Hook(还能暂停!)
前端·javascript·react.js
闲不住的李先森16 分钟前
乐观更新
前端·react.js·设计模式
笔尖的记忆23 分钟前
【前端架构和框架】react组件化&数据流
前端·面试
zhangzelin88831 分钟前
TypeScript入门指南:JavaScript的类型化超集
前端·javascript·其他·typescript
lichenyang45339 分钟前
流式聊天界面实现解析:从零到一构建实时对话体验
前端
天蓝色的鱼鱼39 分钟前
Turbopack vs Webpack vs Vite:前端构建工具三分天下,谁将胜出?
前端·webpack
软件技术NINI1 小时前
html css js网页制作成品——化妆品html+css+js (7页)附源码
javascript·css·html