【Vue3】组件通信之v-model
【Vue3】组件通信之v-model
- 背景
- 简介
- 开发环境
- 开发步骤及源码
- 总结
背景
随着年龄的增长,很多曾经烂熟于心的技术原理已被岁月摩擦得愈发模糊起来,技术出身的人总是很难放下一些执念,遂将这些知识整理成文,以纪念曾经努力学习奋斗的日子。本文内容并非完全原创,大多是参考其他文章资料整理所得,感谢每位技术人的开源精神。
简介
本文介绍 Vue3 中如何使用 v-model
实现组件间通信,即组件间相互传数据。
Vue3 中组件间通信包括:
- 父组件向子组件传数据,实现方案有:
props
v-model
$ref
- 默认插槽 / 具名插槽
- 子组件向父组件传数据
props
v-model
$parent
- 自定义事件
- 作用域插槽
- 父组件向子组件的子组件传数据,即向孙子组件传数据
$attrs
provider
&inject
- 任意组件间传数据
mitt
Pinia
开发环境
分类 | 名称 | 版本 |
---|---|---|
操作系统 | Windows | Windows 11 |
IDE | Visual Studio Code | 1.91.1 |
开发步骤及源码
1> 创建 Vue3 工程,参考:【Vue3】工程创建及目录说明。
2> 删除 src
目录下 assets
和 components
目录。
3> 修改 src
目录下 main.ts
。
import { createApp } from 'vue'
import App from './App.vue'createApp(App).mount('#app')
4> 定义子组件,接收来自父组件的数据。
<template><div class="content"><h1>子组件</h1><span>用户名:</span><input type="text" :value="modelValue"@input="emits('update:modelValue', (<HTMLInputElement>$event.target).value)" /></div>
</template><script setup lang="ts">
defineProps(['modelValue'])
const emits = defineEmits(['update:modelValue'])
</script><style scoped lang="scss">
.content {background-color: greenyellow;padding: 20px;input {border: 3px solid red;height: 30px;line-height: 30px;width: 300px;}
}
</style>
父组件通过 v-model
向子组件传数据,Vue3 框架默认 v-model
传的数据名为 modelValue
,对应事件名为 update:modelValue
,所以子组件需要使用 defineProps
函数声明接收来自父组件的数据 modelValue
,使用 defineEmits
函数声明接收来自父组件的事件 update:modelValue
。
触发事件函数的参数是 $event.target.value
,即子组件中 DOM(input
)事件对象的值。
注意:需要执行 npm install -D sass
命令安装 CSS 预处理器。
5> 修改 Vue 根组件 src/App.vue
,使用 v-model
向子组件传数据。
<template><div class="parent"><Login v-model="username" /></div>
</template><script setup lang="ts">
import Login from './components/Login.vue'
import { ref, watch } from 'vue'const username = ref('administrator')
watch(username, (newValue, oldValue) => {console.log('username changed from', oldValue, 'to', newValue)
})
</script><style scoped lang="scss">
.parent {background-color: orange;padding: 20px;
}
</style>
以上代码中 <Login v-model="username" />
等同于 <Login :modelValue="username" @update:modelValue="username = $event" />
,后者为 v-model
的本质。
6> 执行命令 npm run dev
启动应用,浏览器访问:http://localhost:5173/
。
页面初始化时 <input>
框内显示来自父组件的数据 administrator
,每次修改 <input>
框中数据,控制台便会打印出数据变化日志,此日志为 App.vue
打印的,表明父组件也收到了子组件传来的修改后的变更数据。
7> Vue3 默认 v-model
数据名是 modelValue
,此名称可以自定义。自定义 v-model
数据名便于在同一组件标签上使用多个 v-model
属性传数据,修改 App.vue
向子组件传两个数据。
<template><div class="parent"><Login v-model:account="username" v-model:credential="password" /></div>
</template><script setup lang="ts">
import Login from './components/Login.vue'
import { ref, watch } from 'vue'const username = ref('administrator')
const password = ref('00000000')
watch([username, password], (newValue, oldValue) => {console.log('username changed from', oldValue, 'to', newValue)
})
</script><style scoped lang="scss">
.parent {background-color: orange;padding: 20px;
}
</style>
8> 修改子组件,声明接收父组件的两个数据并进行处理。
<template><div class="content"><h1>子组件</h1><span>用户名:</span><input type="text" :value="account"@input="emits('update:account', (<HTMLInputElement>$event.target).value)" /><span>密码:</span><input type="text" :value="credential"@input="emits('update:credential', (<HTMLInputElement>$event.target).value)" /></div>
</template><script setup lang="ts">
defineProps(['account', 'credential'])
const emits = defineEmits(['update:account', 'update:credential'])
</script><style scoped lang="scss">
.content {background-color: greenyellow;padding: 20px;input {border: 3px solid red;height: 30px;line-height: 30px;margin-right: 20px;width: 300px;}
}
</style>
9> 浏览器刷新访问:http://localhost:5173/
,页面初始化时 <input>
框内显示来自父组件的数据 administrator
和 00000000
,每次修改 <input>
框中数据,控制台便会打印出数据变化日志,此日志为 App.vue
打印的,表明父组件也收到了子组件传来的修改后的变更数据。
总结
- 使用
v-model
实现组件间通信的方法常用于封装自定义 UI 组件库,在日常业务开发过程中较少使用; - 使用
v-model
实现组件间通信的底层原理是:动态 value
+input 事件
; - 父组件需要在子组件标签上通过
v-model
属性标识所传的数据; - 子组件需要使用
defineProps
函数声明接收父组件的数据,使用defineEmits
函数声明接收父组件数据对应的事件; v-model
默认传的数据名为modelValue
,对应事件名为update:modelValue
。数据名可自定义,格式:v-model:自定义数据名
;事件名前缀固定为update:
,格式:update:自定义数据名
。
相关文章:

【Vue3】组件通信之v-model
【Vue3】组件通信之v-model 背景简介开发环境开发步骤及源码总结 背景 随着年龄的增长,很多曾经烂熟于心的技术原理已被岁月摩擦得愈发模糊起来,技术出身的人总是很难放下一些执念,遂将这些知识整理成文,以纪念曾经努力学习奋斗的…...
【Golang 面试 - 进阶题】每日 3 题(二)
✍个人博客:Pandaconda-CSDN博客 📣专栏地址:http://t.csdnimg.cn/UWz06 📚专栏简介:在这个专栏中,我将会分享 Golang 面试中常见的面试题给大家~ ❤️如果有收获的话,欢迎点赞👍收藏…...

Java中等题-多数元素2(力扣)【摩尔投票升级版】
给定一个大小为 n 的整数数组,找出其中所有出现超过 ⌊ n/3 ⌋ 次的元素。 示例 1: 输入:nums [3,2,3] 输出:[3] 示例 2: 输入:nums [1] 输出:[1]示例 3: 输入:num…...
100条超牛的DOS命令
目录 1. 文件和目录管理 1.1 列出文件和目录 1.1.1 dir 1.1.2 dir /w 1.2 切换目录 1.2.1 cd 1.2.2 cd .. 1.3 创建和删除目录 1.3.1 md / mkdir 1.3.2 rd / rmdir 1.4 文件操作 1.4.1 del / erase 1.4.2 copy 1.5 文件重命名 1.5.1 ren / rename 1.5.2 move …...

大数据信用报告查询会不会留下查询记录?怎么选择查询平台?
最近有不少网友都在咨询一个问题,那就是大数据信用报告查询会不会留下查询记录,会不会对自己的征信产生影响,下面本文就详细为大家介绍一下,希望对你了解大数据信用有帮助。 首先、大数据信用与人行征信是独立的 很多人只知道人行…...

JS【详解】内存泄漏(含泄漏场景、避免方案、检测方法),垃圾回收 GC (含引用计数、标记清除、标记整理、分代式垃圾回收)
内存泄漏 在执行一个长期运行的应用程序时,应用程序分配的内存没有被释放,导致可用内存逐渐减少,最终可能导致浏览器崩溃或者应用性能严重下降的情况,即 JS 内存泄漏 可能导致内存泄漏的场景 不断创建全局变量未及时清理的闭包&…...

第三期书生大模型实战营之Llamaindex RAG实践
基础任务 任务要求:基于 LlamaIndex 构建自己的 RAG 知识库,寻找一个问题 A 在使用 LlamaIndex 之前InternLM2-Chat-1.8B模型不会回答,借助 LlamaIndex 后 InternLM2-Chat-1.8B 模型具备回答 A 的能力,截图保存。 streamlit界面…...
【从0到1进阶Redis】Jedis 理解事务
笔记内容来自B站博主《遇见狂神说》:Redis视频链接 小伙伴们可以熟悉一下本专栏的 Redis 文章,可以更好地理解 正常操作 package oldfe.study;import com.alibaba.fastjson.JSONObject; import redis.clients.jedis.Jedis; import redis.clients.jedis.T…...
MySQL之Lost connection to MySQL server during query复现测试
测试Lost connection to MySQL server during query复现条件 环境报错信息复现测试方式一方式二 环境 Python: 3.8/3.9 Mysql: 5.x 报错信息 File "/Users/xxx/lib/python3.9/site-packages/sqlalchemy/dialects/mysql/base.py", line 2509, in do_rollbackdbapi_con…...

中国AI大模型场景探索及产业应用调研报告
AI大模型发展态势 定义 AI大模型是指在机器学习和深度学习领域中,采用大规模参数(至少在一亿个以上)的神经网络模型,AI大模型在训练过程中需要使用大量的算力和高质量的数据资源。 产业规模 2023年,中国大模型市场规模为147亿。结合《202…...

Linux--shell脚本语言—/—<1>
一、shell简介 Shell是一种程序设计语言。作为命令语言,它交互式解释和执行用户输入的命令或者自动地解释和执行预先设定好的一连串的命令;作为程序设计语言,它定义了各种变量和参数,并提供了许多在高级语言中才具有的控制结构&am…...
【java框架开发技术点】通过反射机制调用类中的私有或受保护的方法
示例 假设我们有一个类 ExampleClass,其中有一个私有方法 privateMethod: public class ExampleClass {private void privateMethod(String message) {System.out.println("Private method called with message: " + message);} }我们可以使用上述代码来调用这个…...
你知道这些鼎鼎大名的Java底层核心公司吗
在讨论Java虚拟机——JVM的时候,有几个知名的,不得不提到的JVM的产品和公司。 一、Oracle HotSpot:这是由Sun公司开发的虚拟机。它由最初的Classic VM开始,到推出崭露头角的Exact VM的虚拟机,是现代化高性能虚拟机的最…...

C++入门级文章
一、一个用于查询C标准库内函数、操作符等的链接 https://legacy.cplusplus.com/reference/ 声明:该文档并非官方文档,但其具有易于查询和使用的优势,足够日常使用。 二、C的第一个程序 1、C语言中的语法在C中仍旧适用,首先我们来…...

modelsim仿真quartus IP
开发环境:quartus prime pro 20;modelsim se-64 10.6d 1. 生成Altera的IP库 使用quartus生成IP库,需要使用Simulation Library Compiler(Tools->Launch Simulation Library Compiler) 如下图操作,选择…...

PCB设计经验——布线原则
1.连线精简——避免直角布线 导线也应看作一种元器件,有自己的电阻,电感,电容 PCB走线在直角转弯的地方,信号前后部分相互影响,导致分布电容增加,对信号上升沿和下降沿有延缓影响。从阻抗的角度来说&#…...

C++进阶:设计模式___适配器模式
前言 在C的基础语法的学习后,更进一步为应用场景多写代码.其中设计模式是有较大应用空间. 引入 原本在写容器中适配器类有关的帖子,发现适配模式需要先了解,于是试着先写篇和适配器模式相关的帖子 理解什么是适配器类,需要知道什么是适配器模式.适配器模式是设计模式的一种.笔…...

“八股文“在现代编程面试中的角色重塑:助力、阻力还是桥梁?
🌈所属专栏:【其它】✨作者主页: Mr.Zwq✔️个人简介:一个正在努力学技术的Python领域创作者,擅长爬虫,逆向,全栈方向,专注基础和实战分享,欢迎咨询! 您的点…...
Android 安装应用-浏览阶段
应用安装的浏览阶段主要是由PackageManagerService类中的scanPackageNewLI()实现的,看一下它的代码: // TODO: scanPackageNewLI() and scanPackageOnly() should be merged. But, first, commiting// the results / removing app data needs to be move…...

JavaEE 初阶(10)——多线程8之“单例模式”
目录 一. 设计模式 二. 单例模式 2.1 饿汉模式 2.2 懒汉模式 a. 加锁synchronized b. 双重if判定 c. volatile关键字(双重检查锁定) 一. 设计模式 设计模式是在软件工程中解决常见问题的经典解决方案。针对一些特定场景给出的一些比较好的解决…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...

C++实现分布式网络通信框架RPC(3)--rpc调用端
目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中,我们已经大致实现了rpc服务端的各项功能代…...

超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...

cf2117E
原题链接:https://codeforces.com/contest/2117/problem/E 题目背景: 给定两个数组a,b,可以执行多次以下操作:选择 i (1 < i < n - 1),并设置 或,也可以在执行上述操作前执行一次删除任意 和 。求…...

uniapp微信小程序视频实时流+pc端预览方案
方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度WebSocket图片帧定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐RTMP推流TRTC/即构SDK推流❌ 付费方案 (部分有免费额度&#x…...

ElasticSearch搜索引擎之倒排索引及其底层算法
文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...
docker 部署发现spring.profiles.active 问题
报错: org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...
智能AI电话机器人系统的识别能力现状与发展水平
一、引言 随着人工智能技术的飞速发展,AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术,在客户服务、营销推广、信息查询等领域发挥着越来越重要…...