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

news2024/11/28 20:47:00

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('奥特曼')
	// 声明接收props
	defineProps(['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.coloradmin.cn/o/1603444.html

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

相关文章

javaWeb项目-校园交友网站功能介绍

项目关键技术 开发工具&#xff1a;IDEA 、Eclipse 编程语言: Java 数据库: MySQL5.7 框架&#xff1a;ssm、Springboot 前端&#xff1a;Vue、ElementUI 关键技术&#xff1a;springboot、SSM、vue、MYSQL、MAVEN 数据库工具&#xff1a;Navicat、SQLyog 1、Java语言 Java语…

HTML部分常用标签补充

table&#xff08;布局方面不建议使用&#xff0c;而是使用CSS来完成&#xff09;: 标签解释&#xff1a; ~table标签顾名思义&#xff0c;是表格的意思 ~table其中可以使用boder属性来显示表格的线&#xff0c;最好使用CSS来配合HTML的使用 ~table内的内容可以使用colspan来定…

2024运营级租房源码管理PHP后台+uniapp前端(app+小程序+H5)

内容目录 一、详细介绍二、效果展示1.部分代码2.效果图展示 一、详细介绍 房产系统 一款基于ThinkPHPUniapp开发的房产管理系统&#xff0c;支持小程序、H5、APP&#xff1b;包含房客、房东、经纪人三种身份。核心功能有&#xff1a;新盘销售、房屋租赁、地图找房、房源代理、…

数据结构(七)——B树和B+树

7.4.1_1 B树 5叉查找树 //5叉排序树的结点定义 struct Node {ElemType keys[4]; //最多4个关键字struct Node &child[5]; //最多5个孩子int num; //结点中有几个关键字 }; 如何保证查找效率&#xff1f; eg:对于5叉排序树&#xff0c;规定…

AWS Key disabler:AWS IAM用户访问密钥安全保护工具

关于AWS Key disabler AWS Key disabler是一款功能强大的AWS IAM用户访问密钥安全保护工具&#xff0c;该工具可以通过设置一个时间定量来禁用AWS IAM用户访问密钥&#xff0c;以此来降低旧访问密钥所带来的安全风险。 工具运行流程 AWS Key disabler本质上是一个Lambda函数&…

aws云靶场和一些杂记

aws靶场 在AWS靶场中&#xff0c;存在三个安全问题&#xff1a;1) 一个S3存储桶政策配置错误&#xff0c;允许公共访问&#xff0c;通过访问特定域名可获取flag。2) SQS消息队列的政策没有限制角色&#xff0c;允许发送和接收消息&#xff0c;通过aws sqs命令行工具的receive-…

java八股文知识点讲解(个人认为讲的比较好的)

1、解决哈希冲突——链地址法&#xff1a;【第7章查找】19哈希表的查找_链地址法解决哈希冲突_哔哩哔哩_bilibili 2、解决哈希冲突——开放地址法 &#xff1a; 【第7章查找】18哈希表的查找_开放定址法解决哈希冲突_哔哩哔哩_bilibili 3、小根堆大根堆的创建&#xff1a;选择…

MR-JE-70A 三菱MR-JE伺服驱动器(750W通用型)

三菱MR-JE伺服驱动器(750W通用型) MR-JE-70A外部连接,MR-JE-70A用户手册,MR-JE-70A 三相或单相AC220V三菱通用型伺服放大器750W&#xff0c;配套电机HG-SN52J-S100、HG-KN73J-S100。 MR-JE-70A参数说明&#xff1a;伺服驱动器通用型750W&#xff0c;三相或单相AC200V~240V 三…

reportlab 生成pdf文件 (python)

1 安装 pip install reportlab2 应用场景 通过网页动态生成PDF文档大量的报告和数据发布用XML一步生成PDF 官网案例 3 PLATYPUS Platypus是“Page Layout and Typography Using Scripts”&#xff0c;是使用脚本的页面布局和印刷术的缩写&#xff0c;这是一个高层次页面布局…

媒体邀约的好处?怎么邀请媒体?

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 媒体邀约的好处主要体现在提高品牌知名度、扩大受众群体以及与媒体建立良好的合作关系。 媒体邀约是一种有效的公关策略&#xff0c;通过吸引媒体关注来促进信息的传播。它可以帮助组织…

【笔记】vscode debug进入site-packages包源码

选择左侧栏第三个图标&#xff0c;点击创建 launch.json 文件 选择 Python Debugger 选择Python文件 这里可以看到launch.json 文件 在configurations中添加键值对 "justMyCode": false在文件中打上断点&#xff0c;点击"三角符"号开始调试 按F11或者红框…

双向链表也叫双链表

双向链表也叫双链表 双向链表也叫双链表 每个节点都有两个指针&#xff0c;分别指向 直接前驱节点、直接后继节点 双向链表中任意一个节点&#xff0c;都可以通过通过它的前驱节点和后继节点&#xff0c;访问其他节点 节点如下 节点定义 ListNode // 节点的值 T element; /…

day12-1 | 二叉树 part-1 (Go) | 二叉树的理论基础

今日任务 二叉树的理论基础 ( 参考: 代码随想录) 二叉树种类 二叉树是一种基础数据结构&#xff0c;在算法面试中都是常客&#xff0c;也是众多数据结构的基石。二叉树的定义 和链表是差不多的&#xff0c;相对于链表 &#xff0c;二叉树的节点里多了一个指针&#xff0c; 有…

ArtCoder——通过风格转换生成多元化艺术风格二维码

简介 ArtCoder能够从原始图像&#xff08;内容&#xff09;、目标图像&#xff08;风格&#xff09;以及想要嵌入的信息中&#xff0c;生成具有艺术风格的二维码。这一过程类似于通常的图像风格转换&#xff0c;但特别针对二维码的特点进行了优化和调整。 通过这种方法&#…

MAC电脑M1安装OpenCV

最近在学习研究OpenCV&#xff0c;奈何只有mac电脑。安装OpenCV感觉还是挺麻烦的&#xff0c;所以记录一下&#xff0c;难免以后会忘记。 安装OpenCV我参考的帖子 https://www.bilibili.com/read/cv23613225/ 一、首先安装Anaconda 目前已安装不做赘述 二、启动命令窗口 方…

技术速递|.NET 智能组件简介 – AI 驱动的 UI 控件

作者&#xff1a;Daniel Roth 排版&#xff1a;Alan Wang AI 的最新进展有望彻底改变我们与软件交互和使用软件的方式。然而&#xff0c;将 AI 功能集成到现有软件中可能面临一些挑战。因此&#xff0c;我们开发了新的 .NET 智能组件&#xff0c;这是一组真正有用的 AI 支持的 …

PHP货运搬家/拉货小程序二开源码搭建的功能

运搬家/拉货小程序的二次开发可以添加许多功能&#xff0c;以增强用户体验和提高业务效率。以下是一些可能的功能&#xff1a; 用户端功能&#xff1a; 注册登录&#xff1a;允许用户创建个人账户并登录以使用应用程序。货物发布&#xff1a;允许用户发布他们需要搬运的货物信息…

win2022服务器apache配置https(ssl)真实环境实验(避坑之作)不依赖宝塔小皮等集成环境

本次实验背景&#xff1a; 完全参考官方 https://cloud.tencent.com/document/product/400/4143 文档流程&#xff0c;没有搞定&#xff0c;于是写下避坑之作。 服务器&#xff1a;腾讯云轻量应用服务器 操作系统&#xff1a; Windows Server 2022 DataCenter 64bit CN apache…

rust 学习笔记(13-19)

13 迭代器与闭包 Rust 的设计灵感来源于很多现存的语言和技术。其中一个显著的影响就是 函数式编程&#xff08;functional programming&#xff09;。函数式编程风格通常包含将函数作为参数值或其他函数的返回值、将函数赋值给变量以供之后执行等等。 闭包&#xff08;Closu…

什么Vue?

引入vue.js的方法&#xff1a; <script src"https://cdn.jsdelivr.net/npm/vue2.6.10/dist/vue.js"></script> 例子&#xff1a; v-model&#xff1a;以v-开头的叫做指令 <!DOCTYPE html> <html lang"en"> <head><me…