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('奥特曼')
	// 声明接收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/>

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

最新最全的Jmeter接口测试必会技能:jmeter对图片验证码的处理

jmeter对图片验证码的处理 在web端的登录接口经常会有图片验证码的输入&#xff0c;而且每次登录时图片验证码都是随机的&#xff1b;当通过jmeter做接口登录的时候要对图片验证码进行识别出图片中的字段&#xff0c;然后再登录接口中使用&#xff1b; 通过jmeter对图片验证码…

OpenHarmony南向开发案例【智慧中控面板(基于 Bearpi-Micro)】

1 开发环境搭建 【从0开始搭建开发环境】【快速搭建开发环境】 参考鸿蒙开发指导文档&#xff1a;gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md点击或复制转到。 【注意】&#xff1a;快速上手教程第六步出拉取代码时需要修改代码仓库地址 在MobaXterm中输入…

考研数学|《1800》《660》《880》如何选择和搭配?(附资料分享)

直接说结论&#xff1a;基础不好先做1800、强化之前660&#xff0c;强化可选880/1000题。 首先&#xff0c;传统习题册存在的一个问题是题量较大&#xff0c;但难度波动较大。《汤家凤1800》和《张宇1000》题量庞大&#xff0c;但有些题目难度不够平衡&#xff0c;有些过于简单…

【笔试训练】day4

不到5分钟写完&#xff0c;今天的题又又又难一点啦! 1.Fibonacci数列 思路&#xff1a; 直接模拟一遍斐波那契数列的递增过程&#xff0c;大于n就直接结束。因为后面只会越来越大&#xff0c;跟题目求的最小步数不符。在这个过程中用一个变量去维护这个当前的元素与目标n还差…

IntelliJ IDEA配置类注释模板和方法注释模板

配置类注释模板和方法注释模板 IDEA模板预定义变量类注释模方法注释模板方法参数优化 IDEA模板 在IDEA中&#xff0c;自带的注释模板可能不满足自身需求或者不满意&#xff0c;此时可以通过配置IDEA模板来解决。 预定义变量 内置模板是可编辑的&#xff0c;除了静态文本、代码和…

力扣hot100:136. 只出现一次的数字 及其衍生

文章目录 一、LeetCode&#xff1a;136. 只出现一次的数字 使用到的异或运算的特点&#xff1a; 两个相同的数异或&#xff0c;结果为0 一、LeetCode&#xff1a;136. 只出现一次的数字 LeetCode&#xff1a;136. 只出现一次的数字 这里数组nums的特点是&#xff0c;除了一…

近屿OJAC带你解读:什么是预训练(pre-training)?

预训练&#xff08;Pre-training&#xff09;是深度学习中一种常见的技术&#xff0c;特别是在自然语言处理&#xff08;NLP&#xff09;和计算机视觉等领域。预训练模型的目的是在特定任务之前&#xff0c;先在大量数据上训练一个模型&#xff0c;使其学习到通用的特征和知识。…

EelasticSearch安装及分词器安装

Docker安装 首先在你的linux系统的opt目录下创建一个es7文件夹&#xff0c;然后再在里面创建一个data文件夹&#xff08;data可省略在运行下面命令时它会自动创建&#xff09; docker run -d --name es7 -e ES_JAVA_POTS"-Xms256m -Xmx256m" -e "discovery.ty…

Ai2024安装包(亲测可用)

目录 一、软件简介 二、软件下载 一、软件简介 Adobe illustrator&#xff0c;常被称为“AI”&#xff0c;是一种应用于出版、多媒体和在线图像的工业标准矢量插画的软件。作为一款非常好的矢量图形处理工具&#xff0c;该软件主要应用于印刷出版、海报书籍排版、专业插画、多…

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

5.组件通信方式5-$attrs $attrs的概念&#xff1a; 在Vue中&#xff0c;$attrs 是一个特殊的属性&#xff0c;用于访问父组件向子组件传递的非特定属性。它可以让子组件轻松地获取父组件传递的属性&#xff0c;而无需在子组件中显式声明这些属性。 想象一下你有一个父组件和…

Latent Guard、Tokenization in LLM、​3D Human Scan、FusionPortableV2

本文首发于公众号&#xff1a;机器感知 https://mp.weixin.qq.com/s/HlVV3VnqocBI4XBOT6RFHg A Multi-Level Framework for Accelerating Training Transformer Models The fast growing capabilities of large-scale deep learning models, such as Bert, GPT and ViT, are r…

微软开源 WizardLM-2,70B优于GPT4-0613,7B持平阿里最新的Qwen1.5-32B

当地时间4月15号&#xff0c;微软发布了新一代大语言模型 WizardLM-2&#xff0c;新家族包括三个尖端型号:WizardLM-2 8x22B, WizardLM-2 70B&#xff0c;和WizardLM-2 7B&#xff0c;作为下一代最先进的大型语言模型&#xff0c;它在复杂聊天、多语言、推理和代理方面的性能有…

算法打卡day37

今日任务&#xff1a; 1&#xff09;1049. 最后一块石头的重量 II 2&#xff09;494. 目标和 3&#xff09;474.一和零 4&#xff09;复习day12 1049. 最后一块石头的重量 II 题目链接&#xff1a;1049. 最后一块石头的重量 II - 力扣&#xff08;LeetCode&#xff09; 题目难…

B1100 校庆

输入样例&#xff1a; 5 372928196906118710 610481197806202213 440684198612150417 13072819571002001X 150702193604190912 6 530125197901260019 150702193604190912 220221196701020034 610481197806202213 440684198612150417 370205198709275042 输出样例&#xff1a;…

LINUX中使用cron定时任务被隐藏,咋回事?

一、问题现象 线上服务器运行过程中&#xff0c;进程有莫名进程被启动&#xff0c;怀疑是有定时任务自动启动&#xff0c;当你用常规方法去查看&#xff0c;比如使用crontab去查看定时器任务&#xff0c;提示no crontab for root 或者使用cat到/var/spool/cron目录下去查看定时…

python使用uiautomator2操作真机(华为Honor 10)

环境&#xff1a; python3.8.10&#xff0c;华为手机Honor 10(6G,64g)&#xff0c;版本android 9。 之前写过一篇文章&#xff1a; python使用uiautomator2操作真机_python uiautomator2 控制真机-CSDN博客 今天再拿另外一部手机测试。 一、将手机设置为开发者模式 1、设…

基于ssm冀中工程技师校园网站设计与实现论文

摘 要 使用旧方法对冀中工程技师学院网站的信息进行系统化管理已经不再让人们信赖了&#xff0c;把现在的网络信息技术运用在冀中工程技师学院网站的管理上面可以解决许多信息管理上面的难题&#xff0c;比如处理数据时间很长&#xff0c;数据存在错误不能及时纠正等问题。这次…

【数据恢复软件】:Magnet AXIOM V8.0

Magnet AXIOM V8.0重大更新 1、全新的UI设计 2、更快的相应速度 3、补全工件分析 4、支持亚马逊AWS云数据&#xff08; 获取同一帐户或安全帐户上下文中的快照。 支持Windows实例、加密卷和超过1 TB的卷、具有多个卷的实例等等&#xff01; &#xff09; 5、Bug修复 6、AI支持…

Promise模块化编程ES6新特性

文章目录 Promise&模块化编程1.Promise基本介绍2.快速入门1.需求分析2.原生ajax jQuery3.Promise使用模板 3.课后练习1.原生ajax jQuery2.promise 4.模块化编程基本介绍5.CommonJS基本介绍6.ES5模块化编程1.题目2.示意图3.代码实例—普通导入导出function.jsuse.js 4.代码…

JVM垃圾回收与算法

1. 如何确定垃圾 1.1 引用计数法 在 Java 中&#xff0c;引用和对象是有关联的。如果要操作对象则必须用引用进行。因此&#xff0c;很显然一个简单 的办法是通过引用计数来判断一个对象是否可以回收。简单说&#xff0c;即一个对象如果没有任何与之关 联的引用&#xff0c;即…