Vue3中的常见组件通信之`$refs`、`$parent`

Vue3中的常见组件通信之$refs$parent

概述

​ 在vue3中常见的组件通信有props、mitt、v-model、 r e f s 、 refs、 refsparent、provide、inject、pinia、slot等。不同的组件关系用不同的传递方式。常见的撘配形式如下表所示。

组件关系传递方式
父传子1. props
2. v-model
3. $refs
4. 默认插槽、具名插槽
子传父1. props
2. 自定义事件
3. v-model
4. $parent
5. 作用域插槽
祖传孙、孙传祖1. $attrs
2. provide、inject
兄弟间、任意组件间1. mitt
2. pinia

props和自定义事件详见:
Vue3中的常见组件通信之props和自定义事件
mitt用法详见:
Vue3中的常见组件通信之mitt
v-model用法详见:
Vue3中的常见组件通信之v-model
$attrs用法详见:
Vue3中的常见组件通信之$attrs

接下来是$refs$parent

6. r e f s 、 refs、 refsparent

$refs用于父传子,$parent用于子传父。

6.1准备组件

准备三个组件,一个父组件,两个子组件。

父组件代码:

<template>
	<div class="Father">
		<div id="d1">
			<h3>这是父组件</h3>
			存款:{{ money }} 万元
		</div>

		<Child1/>
		<Child2/>
	</div>	
</template>

<script setup lang="ts" name="Father">
import Child1 from './Child1.vue'
import Child2 from './Child2.vue'
import {ref} from 'vue'

//数据
let money = ref(100)

</script>

<style scoped>
	.Father{
		background-color: rgb(155, 162, 168);
		padding: 10px;
		margin: 10px;
	}
	#d1{
		margin-left: 10px;
	}
</style>

子组件1代码:

<template>
	<div class="Child1">
		<h3>这是子组件1</h3>
		<ul>
			<li>书籍:{{ book }} 本</li>
			<li>玩具:{{ toy }}</li>
		</ul>
	</div>
	
</template>

<script setup lang="ts" name="Child1">
import {ref} from 'vue'

//数据
let book = ref(10)
let toy = ref('滑板车')

</script>

<style scoped>
	.Child1{
		background-color: rgb(132, 114, 148);
		margin: 10px 0;
		padding: 10px;
		color: white;
	}
</style>

子组件2代码:

<template>
	<div class="Child2">
		<h3>这是子组件2</h3>
		<ul>
			<li>书籍:{{ book }} 本</li>
			<li>玩具:{{ toy }}</li>
		</ul>
	</div>	
</template>

<script setup lang="ts" name="Child2">
import {ref} from 'vue'

//数据
let book = ref(6)
let toy = ref('水枪')

</script>

<style scoped>
	.Child2{
		background-color: rgb(128, 132, 31);
		margin-top: 10px;
		padding: 10px;
		color:white
	}
</style>

运行效果如下:

image-20240607145314586

6.2$refs实现父传子通信

需要先了解标签的ref属性的基本知识,ref用在普通DOM标签上,获取的是DOM节点;ref用在组件标签上,获取的是组件实例对象。

了解上面的基础知识后,要在父组件中创建c1和c2,用来存储ref标记的内容:

//创建c1和c2,用于存储ref标记的内容
let c1 = ref()
let c2 = ref()

在CHild1和Ch2组件标签上添加ref属性:

<Child1 ref="c1"/>
<Child2 ref="c2"/>

在Child1和Child2的组件内需要添加以下代码,用来把数据交出去:

//把数据交出去
defineExpose({book,toy})

此时,在父组件中已经拿到了子组件中的数据,可以对这些数据进行操作,如下代码定义一个函数,用来改变子组件1中的toy的值:

function changeC1Toy(){
	c1.value.toy = '积木'
}

在父组件创建按钮,并绑定click事件,用来触发 changeC1Toy函数:

<button @click="changeC1Toy">修改子组件1中的玩具</button>

运行后效果如下:

$refs可以在父组件中获取所有的用ref标记的子组件的实例对象,如果没有用ref标记,则获取不到,例如再增加一个子组件Child3,代码如下:

<template>
	<div class="Child3">
		<h3>这是子组件3</h3>
		<ul>
			<li>书籍:{{ book }} 本</li>
			<li>玩具:{{ toy }}</li>
		</ul>
	</div>
	
</template>

<script setup lang="ts" name="Child3">
import {ref} from 'vue'

//数据
let book = ref(30)
let toy = ref('毛绒玩具')

//把数据交出去
defineExpose({book,toy})
</script>

<style scoped>
	.Child3{
		background-color: rgb(120, 148, 114);
		margin: 10px 0;
		padding: 10px;
		color: white;
	}
</style>

在父组件中引入子组件3:

import Child3 from './Child3.vue'

在页面呈现,但是不添加ref属性

<Child3 />

接下来给父组件创建一个按钮,并绑定click事件,触发changeAllBook()函数,并传入$refs

<button @click="changeAllBook($refs)">修改子组件的书籍数量</button>

changeAllBook的函数代码如下:

function changeAllBook(refs:any){
    console.log(refs)
	for (let key in refs){
		refs[key].book += 1
	}
}

运行后点击按钮,控制台打印的内容如下:

image-20240608161927543

可以看到$refs是一个响应式的对象,对象内是c1和c2,没有子组件3的实例对象。通过遍历把c1和c2中的book增加1,运行效果如下图:

以上通过操控父组件的按钮,实现改变子组件中书籍的数量,这便是父传子通信的一种。

6.3$parent实现子传父通信

$parent的用法与$refs用法类似,$parent获取的是父组件的实例对象,如下在子组件1中添加一个按钮,并绑定单击事件,触发minusMoney方法,实现减少父组件中的存款:

<button @click="minusMoney($parent)">减少父组件存款</button>

minusMoney的代码如下:

function minusMoney(parent:any){	
	parent.money -= 1
}

父组件需要写个宏函数把数据交出去:

//将数据交出去
defineExpose({money})

至此已经完成了子传父的通信,点击子组件中的按钮,可以对父组件中的数据进行操控,如下图:

6.4小结

以上便是$refs$parent实现父子间通信的用法,小结如下:

**$refs:**用来获取所有用ref标记的子组件的实例对象,得到的是响应式对象数据类型,不能获取没有用ref标记的子组件实例对象。

**$parent:**用来获取父组件的实例对象。

注意:组件中需要用宏函数defineExpose()把数据交出去,不然获取不到数据。

以下是完整代码:

父组件:

<template>
	<div class="Father">
		<div id="d1">
			<h3>这是父组件</h3>
			存款:{{ money }} 万元
		</div>
		<button @click="changeC1Toy">修改子组件1中的玩具</button>
		<button @click="changeAllBook($refs)">修改子组件的书籍数量</button>

		<!-- 组件标签的ref属性获取的是组件的实例对象 -->
		<Child1 ref="c1"/>
		<Child2 ref="c2"/>
		<Child3 />
	</div>	
</template>

<script setup lang="ts" name="Father">
import Child1 from './Child1.vue'
import Child2 from './Child2.vue'
import Child3 from './Child3.vue'
import {ref} from 'vue'

//数据
let money = ref(100)

//创建c1和c2,用于存储ref标记的内容
let c1 = ref()
let c2 = ref()

//方法
function changeC1Toy(){
	c1.value.toy = '积木'
}

function changeAllBook(refs:any){
	// console.log(refs)
	for (let key in refs){
		refs[key].book += 1
	}
}

//将数据交出去
defineExpose({money})
</script>

<style scoped>
	.Father{
		background-color: rgb(155, 162, 168);
		padding: 10px;
		margin: 10px;
	}
	#d1{
		margin-left: 10px;
	}
</style>

子组件1

<template>
	<div class="Child1">
		<h3>这是子组件1</h3>
		<ul>
			<li>书籍:{{ book }} 本</li>
			<li>玩具:{{ toy }}</li>
		</ul>
		<button @click="minusMoney($parent)">减少父组件存款</button>
	</div>
</template>

<script setup lang="ts" name="Child1">
import {ref} from 'vue'

//数据
let book = ref(10)
let toy = ref('滑板车')

//方法
function minusMoney(parent:any){	
	parent.money -= 1
}

//把数据交出去
defineExpose({book,toy})
</script>

<style scoped>
	.Child1{
		background-color: rgb(132, 114, 148);
		margin: 10px 0;
		padding: 10px;
		color: white;
	}
	button{
		color: #000;
	}
</style>

子组件2

<template>
	<div class="Child2">
		<h3>这是子组件2</h3>
		<ul>
			<li>书籍:{{ book }} 本</li>
			<li>玩具:{{ toy }}</li>
		</ul>
	</div>	
</template>

<script setup lang="ts" name="Child2">
import {ref} from 'vue'

//数据
let book = ref(6)
let toy = ref('水枪')

//把数据交出去
defineExpose({book,toy})
</script>

<style scoped>
	.Child2{
		background-color: rgb(128, 132, 31);
		margin-top: 10px;
		padding: 10px;
		color:white
	}
</style>

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

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

相关文章

用AI制作历史解说视频:GPT + MidJourney + PiKa + FunSound + 剪映

1. 项目介绍 最近某站看到一个看到利用AI创作视频解说&#xff0c;成品画面很酷炫。对此以初学者视角进行复现&#xff0c;创意来源&#xff1a;用AI制作历史解说视频 2. 开始创作 我们参照原作者展示的内容&#xff0c;对古代人物屈原来生成解说视频。 2.1 故事脚本分镜 【…

IT闲谈-IMD是什么,有什么优势

目录 一、引言二、IDM是什么&#xff1f;三、IDM的优势1. 高速下载2. 稳定性强3. 强大的任务管理4. 视频下载5. 浏览器整合 四、应用场景1. 商务办公2. 教育学习3. 娱乐休闲 总结 一、引言 在数字化时代&#xff0c;下载管理器已成为我们日常工作和生活中不可或缺的工具。而在…

【Java】JDBC+Servlet+JSP实现搜索数据和页面数据呈现

目录 1 .功能介绍 2. 实现流程 3. 项目环境 4. 相关代码 4.1 Maven配置 4.2 SQL语句 4.3 Java代码 4.4 HTML代码 4.5 JSP代码 5. 结果展示 &#xff08;原创文章&#xff0c;转载请注明出处&#xff09; 博主是计算机专业大学生&#xff0c;不定期更新原创优质文章&…

Java基础教程 - 14 Maven项目

更好的阅读体验&#xff1a;点这里 &#xff08; www.doubibiji.com &#xff09; 14 Maven项目 Java 为什么那么强大&#xff0c;很大一部分原因是在实际的开发中&#xff0c;可以将别人开发的模块引入到我们自己的项目中&#xff0c;这样别人开发好了&#xff0c;我拿来就…

Android Media Framework(三)OpenMAX API阅读与分析

这篇文章我们将聚焦Control API的功能与用法&#xff0c;为实现OMX Core、Component打下坚实的基础。 1、OMX_Core.h OMX Core在OpenMAX IL架构中的位置位于IL Client与实际的OMX组件之间&#xff0c;OMX Core提供了两组API给IL Client使用&#xff0c;一组API用于管理OMX组件…

Mysql使用中的性能优化——批量插入的规模对比

在《Mysql使用中的性能优化——单次插入和批量插入的性能差异》中&#xff0c;我们观察到单次批量插入的数量和耗时呈指数型关系。 这个说明&#xff0c;不是单次批量插入的数量越多越好。本文我们将通过实验测试出本测试案例中最佳的单次批量插入数量。 结论 本案例中约每次…

Vue3中的常见组件通信之$attrs

Vue3中的常见组件通信之$attrs 概述 ​ 在vue3中常见的组件通信有props、mitt、v-model、 r e f s 、 refs、 refs、parent、provide、inject、pinia、slot等。不同的组件关系用不同的传递方式。常见的撘配形式如下表所示。 组件关系传递方式父传子1. props2. v-model3. $re…

【机器学习基础】Python编程07:五个实用练习题的解析与总结

Python是一种广泛使用的高级编程语言&#xff0c;它在机器学习领域中的重要性主要体现在以下几个方面&#xff1a; 简洁易学&#xff1a;Python语法简洁清晰&#xff0c;易于学习&#xff0c;使得初学者能够快速上手机器学习项目。 丰富的库支持&#xff1a;Python拥有大量的机…

树莓派4b安装宝塔面板

1、打开命令窗口&#xff0c;执行如下命令 #更新 sudo apt-get update sudo apt-get upgrade #切换root权限 sudo su root #安装宝塔面板 wget -O install.sh http://download.bt.cn/install/install-ubuntu_6.0.sh && bash install.sh安装过程有点久&#xff0c;会持…

如何远程连接Linux服务器?

远程连接Linux服务器是通过网络连接到位于远程位置的Linux服务器&#xff0c;以进行服务器管理和操作。远程连接使得系统管理员可以方便地远程访问服务器&#xff0c;进行配置、维护和故障排除等操作&#xff0c;而不必亲自在服务器前工作。以下是一些常用的远程连接方法&#…

智慧社区整体解决方案

1.智慧社区整体建设方案内容 2.整体功能介绍

NASA数据集——SARAL 近实时增值业务地球物理数据记录海面高度异常

SARAL Near-Real-Time Value-added Operational Geophysical Data Record Sea Surface Height Anomaly SARAL 近实时增值业务地球物理数据记录海面高度异常 简介 2020 年 3 月 18 日至今 ALTIKA_SARAL_L2_OST_XOGDR 这些数据是近实时&#xff08;NRT&#xff09;&#xff…

现代信号处理13_贝叶斯统计Bayesian Statistic(CSDN_20240609)

贝叶斯理论 在传统的统计中&#xff0c;我们对数据是由一定认识的&#xff0c;这种认识一般是指数据的统计模型&#xff08;Statistical Model&#xff09;f(x|θ) &#xff0c;其中θ 通常指未知参数&#xff08;Unknown Parameter&#xff09;&#xff0c;x 是已经获得的数据…

LabVIEW电机槽楔松动声测系统

LabVIEW电机槽楔松动声测系统 开发了一种利用LabVIEW软件和硬件平台&#xff0c;为大型电机设计的槽楔松动声测系统。该系统通过声波检测技术&#xff0c;实现了对电机槽楔是否松动的快速准确判断&#xff0c;极大地提高了检测效率和安全性。 项目背景 大型电机在运行过程中…

[图解]企业应用架构模式2024新译本讲解11-领域模型4

1 00:00:00,160 --> 00:00:01,870 好&#xff0c;到这里的话 2 00:00:02,620 --> 00:00:05,060 文字处理器的产品对象就生成了 3 00:00:06,880 --> 00:00:09,180 同样下面就是电子表格 4 00:00:10,490 --> 00:00:11,480 电子表格也同样的 5 00:00:11,490 -->…

html+CSS+js部分基础运用18

1. 按键修饰符的应用。①姓名&#xff1a;按下回车键时调用方法输出“姓名-密码”&#xff1b;②密码&#xff1a;按下shift回车时调用方法输出“姓名密码” 图1 初始效果图 图2 按键修饰符效果图 2. 仿淘宝Tab栏切换&#xff0c;熟悉…

MySQL使用

登录目标数据库 mysql -u root -p123456或指定编码格式登录 mysql -uroot -p密码 --default-character-setutf8 --socketmysql.sock -Amysql > select version();//查看版本号 show databases;//查看数据库有哪些 use xxx; show tables; show create database practice; …

对待谷歌百度等搜索引擎的正确方式

对待百度、谷歌等搜索引擎的方式是&#xff0c;你要站在搜索引擎之上&#xff0c;保持自己的独立思想和意见。 当谷歌宣布他们将会根据一个名为“Alphabet”的新控股公司来进行业务调整时&#xff0c;在科技界引起了一片恐慌之声。 永远不要说这是一个公司一直在做的事情。不…

攻防世界---misc---What-is-this

1、下载附件&#xff0c;是一个.gz的文件夹&#xff0c;是linux系统的压缩包后缀 2、在kali中解压&#xff0c;解压之后得到两张图片 3、想把图片拖在物理机中分析&#xff0c;但是拖不了&#xff0c;所以将.gz文件在物理机中改为.zip&#xff0c;解压之后看到了一个没有后缀的…

TensorFlow2.x基础与mnist手写数字识别示例

文章目录 Github官网文档Playground安装声明张量常量变量 张量计算张量数据类型转换张量数据维度转换ReLU 函数Softmax 函数卷积神经网络训练模型测试模型数据集保存目录显示每层网络的结果 TensorFlow 是一个开源的深度学习框架&#xff0c;由 Google Brain 团队开发和维护。它…