Vue3 v-bind 和 v-model 对比

1. 基本概念

1.1 v-bind

  • 单向数据绑定
  • 从父组件向子组件传递数据
  • 简写形式为 :

1.2 v-model

  • 双向数据绑定
  • 父子组件数据同步
  • 本质是 v-bind 和 v-on 的语法糖

2. 基础用法对比

2.1 表单元素绑定

vue 复制代码
<!-- v-bind 示例 -->
<template>
  <input :value="text" @input="text = $event.target.value" />
</template>

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

<!-- v-model 示例 -->
<template>
  <input v-model="text" />
</template>

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

2.2 组件属性绑定

vue 复制代码
<!-- v-bind 方式 -->
<template>
  <CustomInput
    :value="searchText"
    @input="searchText = $event"
  />
</template>

<!-- v-model 方式 -->
<template>
  <CustomInput v-model="searchText" />
</template>

3. 主要区别

3.1 数据流向

vue 复制代码
<!-- v-bind: 单向数据流 -->
<ChildComponent
  :title="pageTitle"  <!-- 数据只能从父组件流向子组件 -->
/>

<!-- v-model: 双向数据流 -->
<ChildComponent
  v-model="pageTitle"  <!-- 数据可以双向同步 -->
/>

3.2 实现原理

vue 复制代码
<!-- v-bind 原理 -->
<ChildComponent :value="value" />

<!-- v-model 原理(等价于) -->
<ChildComponent
  :modelValue="value"
  @update:modelValue="value = $event"
/>

3.3 自定义组件实现对比

vue 复制代码
<!-- 使用 v-bind 的组件 -->
<template>
  <div>
    <input
      :value="value"
      @input="$emit('input', $event.target.value)"
    />
  </div>
</template>

<script setup>
defineProps(['value'])
defineEmits(['input'])
</script>

<!-- 使用 v-model 的组件 -->
<template>
  <div>
    <input
      :value="modelValue"
      @input="$emit('update:modelValue', $event.target.value)"
    />
  </div>
</template>

<script setup>
defineProps(['modelValue'])
defineEmits(['update:modelValue'])
</script>

4. 使用场景对比

4.1 适合使用 v-bind 的场景

vue 复制代码
<!-- 1. 纯展示数据 -->
<template>
  <div :class="className">
    <h1 :title="headerTitle">{{ title }}</h1>
    <img :src="imageUrl" :alt="imageAlt" />
  </div>
</template>

<!-- 2. 传递回调函数 -->
<template>
  <button :onClick="handleClick">点击</button>
</template>

<!-- 3. 动态属性 -->
<template>
  <div :[dynamicProp]="value"></div>
</template>

4.2 适合使用 v-model 的场景

vue 复制代码
<!-- 1. 表单控件 -->
<template>
  <input v-model="username" />
  <textarea v-model="description"></textarea>
  <select v-model="selected">
    <option value="">请选择</option>
  </select>
</template>

<!-- 2. 自定义组件的数据同步 -->
<template>
  <CustomInput v-model="searchText" />
  <ColorPicker v-model="themeColor" />
  <DatePicker v-model="selectedDate" />
</template>

<!-- 3. 多个数据的双向绑定 -->
<template>
  <UserForm
    v-model:firstName="user.firstName"
    v-model:lastName="user.lastName"
  />
</template>

5. 性能考虑

5.1 v-bind

  • 单向数据流,性能开销较小
  • 适合大量数据的展示场景
  • 不会触发额外的更新事件

5.2 v-model

  • 双向绑定,需要监听变化
  • 涉及父子组件的数据同步
  • 可能触发多次更新

6. 最佳实践

  1. 选择原则

    • 仅需展示数据时使用 v-bind
    • 需要数据同步时使用 v-model
    • 考虑性能影响选择合适的方式
  2. 代码可维护性

    • v-bind 更直观,易于追踪数据流向
    • v-model 代码更简洁,但需要注意数据追踪
  3. 性能优化

    • 合理使用计算属性
    • 避免不必要的双向绑定
    • 大量数据展示场景优先使用 v-bind
相关推荐
打小就很皮...11 分钟前
HBuilder 发行Android(apk包)全流程指南
前端·javascript·微信小程序
集成显卡1 小时前
PlayWright | 初识微软出品的 WEB 应用自动化测试框架
前端·chrome·测试工具·microsoft·自动化·edge浏览器
前端小趴菜052 小时前
React - 组件通信
前端·react.js·前端框架
Amy_cx2 小时前
在表单输入框按回车页面刷新的问题
前端·elementui
dancing9993 小时前
cocos3.X的oops框架oops-plugin-excel-to-json改进兼容多表单导出功能
前端·javascript·typescript·游戏程序
后海 0_o3 小时前
2025前端微服务 - 无界 的实战应用
前端·微服务·架构
Scabbards_3 小时前
CPT304-2425-S2-Software Engineering II
前端
小满zs3 小时前
Zustand 第二章(状态处理)
前端·react.js
程序猿小D3 小时前
第16节 Node.js 文件系统
linux·服务器·前端·node.js·编辑器·vim
萌萌哒草头将军3 小时前
🚀🚀🚀Prisma 发布无 Rust 引擎预览版,安装和使用更轻量;支持任何 ORM 连接引擎;支持自动备份...
前端·javascript·vue.js