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
相关推荐
衡石科技8 分钟前
一个门户只保留一个智能助理:衡石嵌入式 Data Agent 的运行与渲染边界
前端·javascript·html·data agent
Hilaku9 分钟前
一个前端工程师除了写代码,还能靠什么赚钱?
前端·javascript·程序员
我先测了10 分钟前
Midscene.js 全栈学习指南:从入门到精通的 AI 视觉自动化框架
javascript·人工智能·自动化·agent·midscene
程序员Sunday18 分钟前
JavaScript 闭包是什么?为什么变量没有被释放,什么时候会内存泄漏?
前端·javascript
JarvanMo19 分钟前
Flutter 终于有自己的 React Flow 了,vyuh_node_flow 上手实录
前端
狂师24 分钟前
爆火!新一代e2e AI测试框架,单日狂揽1500 star
前端·人工智能·测试
恋猫de小郭1 小时前
Flitz ,一个把 Flutter 玩成热插拔 Preview 的有趣项目,不错的思路
android·前端·flutter
闭包不眠1 小时前
Word转HTML后体积不对,裁掉的截图原图还在
前端·图像处理·人工智能·计算机视觉·html·word
言乐61 小时前
PythonLOLM自动生成复盘报告模型
开发语言·前端·数据库·人工智能·python
tryCbest1 小时前
第二篇:CSS3 全部知识点全解 + 项目样式实现
前端·css·css3