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
相关推荐
南玖i1 小时前
vue3 通过 Vue3DraggableResizable实现拖拽弹窗,可修改大小
前端·javascript·vue.js
excel1 小时前
Web发展与Vue.js导读
前端
YAY_tyy1 小时前
Three.js 开发实战教程(五):外部 3D 模型加载与优化实战
前端·javascript·3d·three.js
Zuckjet_4 小时前
开启 3D 之旅 - 你的第一个 WebGL 三角形
前端·javascript·3d·webgl
2401_863801464 小时前
探索 12 种 3D 文件格式:综合指南
前端·3d
珍宝商店6 小时前
前端老旧项目全面性能优化指南与面试攻略
前端·面试·性能优化
bitbitDown6 小时前
四年前端分享给你的高效开发工具库
前端·javascript·vue.js
YAY_tyy6 小时前
【JavaScript 性能优化实战】第六篇:性能监控与自动化优化
javascript·性能优化·自动化
gnip7 小时前
实现AI对话光标跟随效果
前端·javascript
脑花儿8 小时前
ABAP SMW0下载Excel模板并填充&&剪切板方式粘贴
java·前端·数据库