news 2026/5/1 6:27:10

VUE3:深入浅出双向传值的历史用法变化

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
VUE3:深入浅出双向传值的历史用法变化

什么是双向绑定?

双向绑定就是:父组件的数据变了,子组件跟着变;子组件修改了,父组件也跟着变。就像两个人拉着同一根绑带,一个人动,另一个人也跟着动。

演变历史

Vue 2 → Vue 3.0~3.3 → Vue 3.4+ v-model defineEmits + defineModel .sync修饰符 defineProps (超级简化!)

方式一:Vue 3.4 之前的写法(defineEmits + defineProps)

这是"传统"写法,需要分别定义 props 接收和 emit 发送。

父组件
<template> <div class="parent"> <h2>👨 父组件 - Vue 3.4 之前的双向绑定</h2> <p>父组件的 message: {{ message }}</p> <!-- v-model 是语法糖,等价于: :modelValue="message" @update:modelValue="val => message = val" --> <ChildOldWay v-model="message" /> <!-- 多个 v-model 的写法 --> <ChildOldWay v-model:title="title" v-model:content="content" /> </div> </template> <script setup> import { ref } from 'vue' import ChildOldWay from './ChildOldWay.vue' const message = ref('Hello Vue!') const title = ref('文章标题') const content = ref('文章内容') </script>
子组件(旧写法)
<template> <div class="child"> <h3>👶 子组件 - 旧写法</h3> <!-- 显示从父组件接收的值 --> <p>接收到的值: {{ modelValue }}</p> <!-- 子组件不能直接修改 props! 需要通过 emit 通知父组件修改 --> <input :value="modelValue" @input="updateValue" placeholder="输入新值" /> <button @click="emit('update:modelValue', '被子组件修改了')"> 直接修改 </button> </div> </template> <script setup> // ========== 第一步:用 defineProps 接收父组件的值 ========== const props = defineProps({ // v-model 默认绑定的 prop 名是 modelValue modelValue: { type: String, default: '' }, // 自定义名称的 v-model,如 v-model:title title: String, content: String }) // ========== 第二步:用 defineEmits 定义事件 ========== // 事件名必须是 'update:属性名' 的格式 const emit = defineEmits([ 'update:modelValue', // 对应 v-model 'update:title', // 对应 v-model:title 'update:content' // 对应 v-model:content ]) // ========== 第三步:通过 emit 通知父组件更新 ========== const updateValue = (event) => { // 发射事件,让父组件更新数据 emit('update:modelValue', event.target.value) } </script>

方式二:Vue 3.4+ 新写法(defineModel)🎉

Vue 3.4 引入了defineModel,大大简化了双向绑定的代码!

父组件(和之前一样)
<template> <div class="parent"> <h2>👨 父组件 - Vue 3.4+ 新写法</h2> <p>父组件的 message: {{ message }}</p> <p>父组件的 count: {{ count }}</p> <!-- 用法和之前完全一样 --> <ChildNewWay v-model="message" v-model:count="count" /> </div> </template> <script setup> import { ref } from 'vue' import ChildNewWay from './ChildNewWay.vue' const message = ref('Hello Vue 3.4!') const count = ref(0) </script>
子组件(新写法 - 超级简化!)
<template> <div class="child"> <h3>👶 子组件 - Vue 3.4+ defineModel</h3> <!-- model 就像一个普通的 ref,可以直接读写! 不需要 :value + @input,直接 v-model 绑定 --> <input v-model="model" placeholder="直接双向绑定" /> <p>当前值: {{ model }}</p> <!-- 多个 model 也很简单 --> <button @click="count++">count: {{ count }}</button> </div> </template> <script setup> // ======================================== // Vue 3.4+ 的 defineModel:一行搞定! // ======================================== // 默认的 v-model // defineModel() 返回一个 ref,可以直接读写 const model = defineModel() // 带名称的 v-model:count const count = defineModel('count') // 带类型和默认值 // const model = defineModel({ type: String, default: '默认值' }) // 就这么简单! // - 不需要 defineProps // - 不需要 defineEmits // - 不需要手动 emit // - 直接读写就能双向绑定 </script>

对比总结

<!-- ❌ Vue 3.4 之前:繁琐 --> <script setup> const props = defineProps(['modelValue']) const emit = defineEmits(['update:modelValue']) // 使用时:emit('update:modelValue', newValue) </script> <!-- ✅ Vue 3.4+ 之后:简洁 --> <script setup> const model = defineModel() // 使用时:model.value = newValue(直接赋值!) </script>

对比项

旧写法 (defineProps + defineEmits)

新写法 (defineModel)

代码量

多(至少3行)

少(1行)

复杂度

需要理解 emit 机制

像普通 ref 一样使用

可读性

一般

非常好

Vue版本

3.0+

3.4+

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/28 4:11:45

22、SNMP与跨平台Unix编程:Python的强大应用

SNMP与跨平台Unix编程:Python的强大应用 1. SNMP查询与工具创建 SNMP(简单网络管理协议)在网络管理中扮演着重要角色。首先,我们来看一个SNMP查询的例子: Running snmp query for: 10.0.1.20sysDescr = None ( None ) 10.0.1.20 returns (Linux localhost.localdoma…

作者头像 李华
网站建设 2026/5/1 0:54:12

如何在本地部署EmotiVoice开源TTS模型?完整教程

如何在本地部署 EmotiVoice 开源 TTS 模型&#xff1f;完整实战指南 你有没有想过&#xff0c;让一段文字“说出”愤怒、喜悦甚至哽咽的语气&#xff1f;或者只需几秒钟录音&#xff0c;就让 AI 用亲人的声音为你朗读文章&#xff1f;这些曾经属于科幻场景的能力&#xff0c;如…

作者头像 李华
网站建设 2026/4/24 12:12:37

30、Python 并发编程:线程、进程与守护进程全解析

Python 并发编程&#xff1a;线程、进程与守护进程全解析1. 线程编程基础在 Python 中&#xff0c;线程是实现并发的一种重要方式。以下是一个简单的线程池示例代码&#xff1a;worker.start() #spawn pool of arping threads for i in range(num_arp_threads):worker Thread(…

作者头像 李华
网站建设 2026/4/25 0:54:17

DeepSeek-Math 数学AI实战指南:7个核心技巧让你快速上手

DeepSeek-Math 数学AI实战指南&#xff1a;7个核心技巧让你快速上手 【免费下载链接】DeepSeek-Math 项目地址: https://gitcode.com/GitHub_Trending/de/DeepSeek-Math 还在为复杂的数学问题发愁吗&#xff1f;DeepSeek-Math这个强大的数学推理AI工具&#xff0c;能帮…

作者头像 李华
网站建设 2026/4/24 22:36:55

函数指针结构体在单片机应用,怎么理解与回到函数区别

在单片机应用中,回调函数是一种 “间接调用函数” 的编程思想,而函数指针结构体是对回调函数的 “存储、组织和封装方式”—— 两者并非对立关系,而是 **“设计思想” 与 “实现载体”的关系。函数指针结构体解决了单一回调函数在单片机中多实例管理、状态与回调分离、模块化…

作者头像 李华
网站建设 2026/4/18 8:03:45

Shutter Encoder视频转换神器:从小白到高手的效率革命

还在为视频格式转换而烦恼吗&#xff1f;想要一次性处理上百个媒体文件却苦于找不到合适的工具&#xff1f;今天我要向你介绍一款真正改变游戏规则的多媒体处理工具——Shutter Encoder视频转换神器。这款基于FFmpeg的专业工具&#xff0c;让复杂的视频操作变得像拖拽一样简单。…

作者头像 李华