Vue3从入门到实战:深度掌握组件通信(上部曲)

props的概念:

当你使用Vue 3的组合式API时,props就是一种让你可以从父组件向子组件传递数据的方式。你可以想象成你在给子组件写一封信,把需要传递的信息放在信封里。

在Vue 3中,你可以在子组件的代码中定义props,就像在信封上写下你需要传递的信息的名字。你可以指定每个props的类型,比如是字符串、数字等等,这样Vue就会帮你确保接收到的数据是正确的类型。

你还可以指定props是否是必需的,就像是你在信封上写着"必须打开",这样别人在使用你的组件时就必须传递这个props,否则会出现警告。

如果你给props设置了默认值,就像是在信封里放了一张字条,如果别人没有传递这个props,那么组件就会使用默认值。

当父组件给子组件传递了props,子组件就可以在自己的代码中使用这些props了,就像是打开了你传递的信封,取出里面的信息。你可以根据需要对这些props进行处理和计算,就像是读取信中的内容并进行一些操作。

 假设在App组件的框架下,里面有众多的组件,其中A组件的数据和B组件如何进行交互呢?

答案:组件通信

 1.组件通信方式1-props

若父传子:属性值是非函数。  

如图:左边是父组件,右边是子组件


若 **子传父**:属性值是**函数**。

子传父:

  1. 接受子子组件传来的东西需要提前定义一个方法getToy
  2.  把getToy传给子组件
  3. 子那边要照样接收
  4. 直接使用父传来的,记得要加参数

 

Child.vue子组件代码: 

<template><div class="child"><h3>子组件</h3><h4>玩具:{{ toy }}</h4><h4>父给的车:{{ car }}</h4><button @click="sendToy(toy)">把玩具给父亲</button></div>
</template><script setup lang="ts" name="Child">import {ref} from 'vue'// 数据let toy = ref('奥特曼')// 声明接收propsdefineProps(['car','sendToy'])
</script><style scoped>.child{background-color: skyblue;padding: 10px;box-shadow: 0 0 10px black;border-radius: 10px;}
</style>

 Father.vue父组件代码

<template><div class="father"><h3>父组件</h3><h4>汽车:{{ car }}</h4><h4 v-show="toy">子给的玩具:{{ toy }}</h4><Child :car="car" :sendToy="getToy"/></div>
</template><script setup lang="ts" name="Father">import Child from './Child.vue'import {ref} from 'vue'// 数据let car = ref('奔驰')let toy = ref('')// 方法function getToy(value:string){toy.value = value}
</script><style scoped>.father{background-color:rgb(165, 164, 164);padding: 20px;border-radius: 10px;}
</style>

补充:

v-show指v的是如果不点击按钮,就没有参数接受,就不会显示信息,否则则显示出来

2.组件通信方式2-自定义事件

自定义事件的概念:

当我们在Vue 3中需要让组件之间进行通信时,可以使用自定义事件。可以把自定义事件想象成人与人之间的交流,就像你和朋友之间通过说话来传递信息一样。

在Vue 3中,我们可以在一个组件中触发自定义事件,就像你向朋友说出一句话一样。你可以使用$emit方法来触发事件,并传递一些数据作为事件的参数。

而在另一个组件中,你可以监听并响应这个自定义事件,就像是朋友听到你的话后做出回应。你可以使用$on方法来监听事件,并在事件触发时执行相应的逻辑。

通过自定义事件,不同的组件可以进行灵活的交流和信息传递,就像是人们通过说话来相互沟通。这样就可以实现组件之间的解耦,让它们能够独立地进行通信。

概述:自定义事件常用于:子 => 父。

  1. 给子组件绑定了一个send-toy事件,只要点击就会调用saveToy,这就是自定义事件
  2. 如何触发send-toy事件呢?在子组件defineEmits声明中放入该事件
  3. 然后只要调用emit('send-toy')就可以触发了

 Child.vue子组件代码: 

<template><div class="child"><h3>子组件</h3><h4>玩具:{{ toy }}</h4><button @click="emit('send-toy',toy)">测试</button></div>
</template><script setup lang="ts" name="Child">import { ref } from "vue";// 数据let toy = ref('奥特曼')// 声明事件const emit =  defineEmits(['send-toy'])
</script><style scoped>.child{margin-top: 10px;background-color: rgb(76, 209, 76);padding: 10px;box-shadow: 0 0 10px black;border-radius: 10px;}
</style>

  Father.vue父组件代码:

<template><div class="father"><h3>父组件</h3><h4 v-show="toy">子给的玩具:{{ toy }}</h4><!-- 给子组件Child绑定事件 --><Child @send-toy="saveToy"/></div>
</template><script setup lang="ts" name="Father">import Child from './Child.vue'import { ref } from "vue";// 数据let toy = ref('')// 用于保存传递过来的玩具function saveToy(value:string){console.log('saveToy',value)toy.value = value}
</script><style scoped>.father{background-color:rgb(165, 164, 164);padding: 20px;border-radius: 10px;}.father button{margin-right: 5px;}
</style>

 3.组件通信方式3-mitt

mitt的概念:

"Mitt" 是一个小而灵活的JavaScript库,用于在应用程序中处理事件的订阅和发布。可以把它想象成一个事件调度中心,就像是一个小管家,帮助不同的组件之间进行信息传递和交流。

当我们需要在应用程序中的不同部分之间传递消息时,可以使用 "Mitt" 来管理这些消息。它提供了一种简单的方式来订阅事件和触发事件。

假设你有几个组件,它们需要相互通信。你可以创建一个 "Mitt" 的实例,就像是雇佣了一个小管家。然后,你可以让组件们通过 "Mitt" 的实例来订阅事件,就像是告诉小管家:“如果有人说了某个事件,告诉我一声”。

当某个组件需要发送一个事件时,它可以通过 "Mitt" 的实例来触发该事件,就像是对小管家说:“有人说了某个事件,快去告诉其他组件”。

然后,其他组件就会收到这个事件,并可以根据需要做出响应,就像是收到小管家传递的消息后采取相应的行动。

"Mitt" 的好处在于它的简洁性和灵活性。它不依赖于任何特定的框架或库,可以在各种环境中使用。它是一个轻量级的解决方案,但非常实用,可以帮助你构建松散耦合的应用程序,让组件之间的通信更加方便和可靠。

通过mitt可以任意组件传递数据

比如如下的A组件通过绑定emitter,然后B组件触发emitter就可以获得A组件数据,爽完。

$event.target
event是触发对象事件,target是发生三个事件的本体

双向绑定:页面和控制台绑定,即在那面修改信息,另外也会发生变化 

概述:与消息订阅与发布(`pubsub`)功能类似,可以实现任意组件间通信。
1.安装mitt  

npm i mitt

 

2.新建文件:src\utils\emitter.ts  

emitter.ts文件代码:

// 引入mitt
import mitt from 'mitt'// 调用mitt得到emitter,emitter能:绑定事件、触发事件
const emitter = mitt()// 暴露emitter
export default emitter

 3.接收数据的组件中:绑定事件、同时在销毁前解绑事件

 


4.组件通信方式4-v-model (重点)

v-model的概念:

当我们在构建一个交互性的网页或应用程序时,很常见的需求是让用户能够输入数据并与之进行交互。Vue中的 v-model 就是为了解决这个需求而设计的。

想象一下你有一个输入框,用户可以在里面输入文本。你希望能够获取用户输入的值,并将其保存到Vue实例中的一个数据属性中,以便后续使用。同时,你也希望当你在Vue实例中修改了这个数据属性的值时,输入框中的内容也能够自动更新。

这就是 v-model 的作用啦!它是Vue中的一个特殊指令,让你可以将输入框和Vue实例中的数据属性绑定在一起,实现双向的数据绑定。

当你在输入框中输入文本时,v-model 会自动将输入的值保存到Vue实例中的数据属性中。而当你在Vue实例中修改了这个数据属性的值时,v-model 会自动将最新的值显示在输入框中。

这就像是你和Vue实例之间建立了一条数据的通道:你可以通过输入框向Vue实例发送数据,同时也可以通过修改Vue实例中的数据属性来控制输入框的内容。

需要注意的是,v-model 并不仅限于输入框,还可以用于复选框、单选按钮等表单元素,甚至是自定义的组件。

4.1 v-model用在html标签上

1.双向绑定:控制台的信息能显示在页面上,同时哪边被修改了都可以同步。

2.控制台数据的信息呈现在页面上 

3.在页面修改信息,控制台数据同步信息

 这里是程序员要写的v-model的代码:

<input type="text" v-model="username">

其实这段代码的本质是:

<input type="text" :value="username" @input="username = (<HTMLInputElement>$event.target).value">

底层原理是动态的value值和input事件

这两段代码是等价的

补充:

为什么报警告呢?

输入担心不是html输入类型的元素。所有要<HTMLInputElement>来断言告诉它不用担心。


4.2. v-model用在组件标签上 

我们先写一个组件:

该组件的作用是改变输入框的样式。

<template><input ><br><input >
</template><script setup lang="ts" name="MyInput"></script><style scoped>input {border: 2px solid black;background-image: linear-gradient(45deg,red,yellow,green);height: 30px;font-size: 20px;color: white;}
</style>

然后在father.vue组件增添代码:

 <MyInput v-model="username"/>

 这段代码的本质:

<MyInput :modelValue="username" @update:modelValue="username = $event"/>

:modelvalue传过来"username",实现控制台数据呈现到页面上  

@update:modelValue只是事件名,它绑定username这个事件

然后在MyInput.vue组件上修改:

1.用defineProps把modelvalue名接收了

2.呈现在input输入框中

上面两步是把控制台数据呈现到页面。

3. 用defineEmits把input事件里的update:modelValue接收了

4.同理,把它用在输入框中。

上面两步代码是在页面上修改数据时,也可以绑定控制台数据

 

 其实MyInput.vue类似UI库里面的组件,我这么写是为了解释<MyInput v-model="username"/>底层逻辑的实现,实际开发中,直接写<MyInput v-model="username"/>就好了。

补充:

$event到底是啥? 啥时候能.target?
对于原生事件,$event就是事件对象 =====>能.target
对于自定义事件,$event就是触发事件时,所传递的数据 ==>不能target

 MyInput.vue代码:

<template><input type="text" :value="modelValue"@input="emit('update:modelValue',(<HTMLInputElement>$event.target).value)">
</template><script setup lang="ts" name="MyInput">
defineProps(['modelValue'])const emit = defineEmits(['update:modelValue'])
</script><style scoped>input {border: 2px solid black;background-image: linear-gradient(45deg,red,yellow,green);height: 30px;font-size: 20px;color: white;}
</style>

Father.vue文件代码:

<template><div class="father"><h3>父组件</h3><!-- v-model用在html标签上 1.程序员写的代码  <input type="text" v-model="username">1.等价于下面这段代码<input type="text" :value="username" @input="username = (<HTMLInputElement>$event.target).value">  --><!-- v-model用在组件标签上 2.程序员写的代码     <MyInput v-model="username"/>2.等价于下面这段代码<MyInput :modelValue="username" @update:modelValue="username = $event"/>  --></div>
</template><script setup lang="ts" name="Father">import { ref } from "vue";import MyInput from './MyInput.vue'// 数据let username = ref('zhansgan')
</script><style scoped>
.father {padding: 20px;background-color: rgb(165, 164, 164);border-radius: 10px;
}
</style>

4.3v-model的细节

<!-- 也可以更换value,例如改成abc-->
<MyInput v-model:ming="userName"/><!-- 上面代码的本质如下 -->
<MyInput :ming="uerName" @update:ming="userName = $event"/>

MyInput.vue文件中代码:

<template><input type="text" :value="modelValue"@input="emit('update:ming',(<HTMLInputElement>$event.target).value)">
</template>ming<script setup lang="ts" name="MyInput">
defineProps(['ming'])const emit = defineEmits(['update:ming'])
</script><style scoped>input {border: 2px solid black;background-image: linear-gradient(45deg,red,yellow,green);height: 30px;font-size: 20px;color: white;}
</style>

 如果value可以更换,那么就可以在组件标签上多次使用v-model

比如:

<MyInput v-model:ming="userName" v-model:mima="password/>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/824006.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Dryad Girl Fawnia

一个可爱的Dryad Girl Fawnia的三维模型。她有ARKit混合形状,人形装备,多种颜色可供选择。她将是一个完美的角色,幻想或装扮游戏。 🔥 Dryad Girl | Fawnia 一个可爱的Dryad Girl Fawnia的三维模型。她有ARKit混合形状,人形装备,多种颜色可供选择。她将是一个完美的角色…

Web 题记

[极客大挑战 2019]LoveSQL 看到这种就肯定先想到万能密码&#xff0c;试试&#xff0c;得到了用户名和密码 总结了一些万能密码&#xff1a; or 11 oror admin admin-- admin or 44-- admin or 11-- admin888 "or "a""a admin or 22# a having 11# a havin…

Unity引擎Shader 技术点解释

Shader 类 定义&#xff1a; Shader 类是 Unity 中用于封装着色器程序的实例。它允许开发者在同一个文件中定义多个着色器程序&#xff0c;并指导 Unity 如何使用它们。 兼容性&#xff1a; Shader 类需要与 Unity 的渲染管线兼容。Unity 提供了两种主要的渲染管线&#xf…

C++ 之 newmat 矩阵运算库使用笔记

文章目录 Part.I IntroductionChap.I newmat 简介 Part.II 安装与编译Chap.I 直接使用源码Chap.II 基于 CMake 使用源码Chap.III 编译成库 Part.III 关于矩阵的构造与运算Chap.I 矩阵的构造与初始化Chap.II 矩阵的运算Chap.III 矩阵维数和类型的更改Chap.IV 矩阵最值统计 Refer…

【避坑/个人总结】CARLA仿真遇到问题——AttributeError: module “numpy“ has no attribute “bool“

问题描述 执行以下命令时&#xff1a; ./CarlaUE4.sh -prefernvidia // 以及 ros2 launch carla_shenlan_bridge_ego_vis carla_bridge_ego_vehilce.launch.py 出现以下的问题&#xff1a; 其中的报错类型及具体为&#xff1a;AttributeError: module "numpy" has…

线下商家地图标注服务/店铺地图定位/商铺地图标注服务源码

简介&#xff1a; 前台 单店标注信息提交&#xff0c; 连锁店标注信息提交 &#xff0c;支付订单查询&#xff0c;用户问题反馈 后台 系统基本设置&#xff0c;反馈信息查看&#xff0c;订单信息管理&#xff0c;地图信息管理&#xff0c;管理员密码设置&#xff0c;集成微信…

香港科技大学广州|数据科学与分析学域硕博招生宣讲会—华东师范大学专场

时间&#xff1a;2024年4月25日&#xff08;星期四&#xff09;13:30 地点&#xff1a;华东师范大学普陀校区文附楼507 报名链接&#xff1a;https://www.wjx.top/vm/Q0cKTUI.aspx# 跨学科研究领域 *数据驱动的人工智能和机器学习 *统计学习和建模 工业和商业分析 *特定行业…

鲲鹏920RDMA应用示例代码

当前针对鲲鹏920服务器&#xff0c;编写了RDMA通信传输代码&#xff0c;首先采用TCP socket进行管理信息获取&#xff0c;然后调用verbs函数接口进行数据传输。需要安装rdma-core-devel库才可以编译 代码如下&#xff1a; /** rdma_lib.h** Created on: 2021年1月1日* A…

在Linux系统中设定延迟任务

一、在系统中设定延迟任务要求如下&#xff1a; 要求&#xff1a; 在系统中建立easylee用户&#xff0c;设定其密码为easylee 延迟任务由root用户建立 要求在5小时后备份系统中的用户信息文件到/backup中 确保延迟任务是使用非交互模式建立 确保系统中只有root用户和easylee用户…

【NUCLEO-G071RB】004——GPIO-按键EXTI外部中断控制LED闪烁

NUCLEO-G071RB&#xff1a;004——GPIO-按键EXTI外部中断控制LED闪烁 设计目标电路原理图芯片配置程序修改 设计目标 电路原理图 与NUCLEO-G071RB&#xff1a;003——GPIO-按键控制LED灯相同 芯片配置 1、PC13&#xff08;B1&#xff09;&#xff1a;EXTI外部中断模式&…

Linux LVM 逻辑卷管理

Logical Volume Manager&#xff0c;逻辑卷管理 能够在保持现有数据不变的情况下动态调整磁盘容量&#xff0c;从而提高磁盘管理的灵活性/boot分区用于存放引导文件&#xff0c;不能基于LVM创建 三大概念&#xff1a; 物理卷PV基于硬盘或分区设备创建而来&#xff0c;生成N多…

基于SpringBoot的“滴答拍摄影项目”的设计与实现(源码+数据库+文档+PPT)

基于SpringBoot的“滴答拍摄影项目”的设计与实现&#xff08;源码数据库文档PPT) 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBoot 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 滴答拍摄影项目结构图 管理员登录首页界面图 用…

【Linux】git

大家好&#xff0c;我是苏貝&#xff0c;本篇博客带大家了解Linux的编译器-gcc/g&#xff0c;如果你觉得我写的还不错的话&#xff0c;可以给我一个赞&#x1f44d;吗&#xff0c;感谢❤️ 目录 1.安装git2.在gitee上创建仓库3.首次配置4.下载仓库到本地5.三板斧6.git log7.gi…

待研究技术

Fabric.js H5 Canvas的js库 Fabric.js是一个用于创建交互式的HTML5 Canvas应用程序的JavaScript库。它提供了一个简单而强大的API&#xff0c;用于在Web浏览器中绘制和操作图形对象。Fabric.js可以用于创建各种图形应用程序&#xff0c;例如绘图编辑器、图像编辑器、流程图、地…

JavaSE-13笔记【集合2(+2024新)】

文章目录 3.Map3.1 Map继承结构3.2 Map接口的常用方法3.3 遍历Map3.4 HashMap集合3.4.1 HashMap集合key的特点3.4.2 HashMap集合的key存储自定义类型3.4.3 哈希表3.4.3.1 哈希表的介绍3.4.3.2 哈希表的存储原理 3.4.4 存放在HashMap和HashSet集合key部分的元素必须同时重写hash…

2024年在Vim中开发vue2+java

neovim 0.5刚出来的时代&#xff0c;那时刚有lua插件我很狂热。每天沉迷于打造自己的IDE之中。写过一堆相关的博客&#xff0c;也录过一些视频教程。后来发现neovim的接口和插件更新的很快&#xff0c;导致配置文件要不定期的修改&#xff0c;才能保证新版本的插件的适配。我也…

理解思维链Chain of Thought(CoT)

Chain of Thought&#xff08;CoT&#xff09;&#xff0c;即“思维链”&#xff0c;是人工智能领域中的一个概念&#xff0c;特别是在自然语言处理和推理任务中。它指的是一种推理过程&#xff0c;其中模型在生成最终答案之前&#xff0c;先逐步推导出一系列的中间步骤或子目标…

部署Zabbix5.0

一.部署zabbix客户端 端口号10050 zabbix 5.0 版本采用 golang 语言开发的新版本客户端 agent2 。 zabbix 服务端 zabbix_server 默认使用 10051 端口&#xff0c;客户端 zabbix_agent2 默认使用 10050 端口。 1.1.关闭防火墙和selinux安全模块 systemctl disable --now fir…

json diff patch

文件和图片的比对靠字符串 目录 流程 安装 效果 使用 自适应 数组&#xff1a;最长公共子序列(LCS) 数组中的对象&#xff0c;给定id&#xff0c;类似dom tree的比较 流程 安装 npm install jsondiffpatch import * as jsondiffpatch from jsondiffpatch; const jsond…

Vue3(六):Vue3其他API、Vue3新组件Teleport、Vue2和3区别

一、其他API 1.shallowRef 与 shallowReactive &#xff08;1&#xff09;shallowRef 1. 作用&#xff1a;创建一个响应式数据&#xff0c;但只对顶层属性进行响应式处理。 2.用法&#xff1a; let myVar shallowRef(initialValue); 3. 特点&#xff1a;只跟踪引用值的变化&…