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>

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

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

相关文章

Vue数据动态代理机制的实现

Object.defineProperty() &#xff08;1&#xff09;这个方法是ES5新增的 &#xff08;2&#xff09;这个方法的作用是&#xff1a;给对象新增属性&#xff0c;或者设置对象原有的属性 &#xff08;3&#xff09;用法&#xff1a;Object.defineProperty(给哪个对象新增属性,‘…

【虚拟现实】一、AR与VR的基本原理

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 增强现实&#xff08;AR&#xff09;和虚拟现实&#xff08;VR&#xff09;技术已经从科幻小说走入现实&#xf…

UR机器人通信汇总

文章目录 一、概述二、UR机器人通信2.1UR通信协议2.2 UR通信端口 三、UR机器人通信端口类型3.1 Modbus TCP端口&#xff08;502端口&#xff09;3.2 Dashboard端口&#xff08;29999端口&#xff09;3.3 上位机编程端口&#xff08;30001/30002/30003端口&#xff09;3.3.1 URS…

linux本地搭建dns

不需要图形化界面 使用的是dnsmasq&#xff0c;配置简单 1.安装 deb系列linux apt-get install dnsmasqrhat系列linux yum install dnsmasq2.编辑配置文件 vi /etc/dnsmasq.conf设置主dns服务器&#xff0c;比如现有公用的的114.114.114.114 8.8.8.8这类的 server8.8.8.8…

字节开源Hyper-SD模型,超越SDXL-Lightning,单步生成SOTA级图像

前言 近年来&#xff0c;扩散模型&#xff08;Diffusion Model&#xff0c;DM&#xff09;在图像生成领域取得了显著进展&#xff0c;展现出前所未有的图像质量和多样性。然而&#xff0c;扩散模型的训练和推理过程通常需要多个步骤&#xff0c;这限制了其在实际应用中的效率。…

注册小程序

每个小程序都需要在 app.js 中调用 App 方法注册小程序实例&#xff0c;绑定生命周期回调函数、错误监听和页面不存在监听函数等。 详细的参数含义和使用请参考 App 参考文档 。 整个小程序只有一个 App 实例&#xff0c;是全部页面共享的。开发者可以通过 getApp 方法获取到全…

172.二叉树:左叶子之和(力扣)

代码解决 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr, right(nullptr) {}* Tree…

RandomDate(接口参数化-随机生成日期)

目录 1、入口位置&#xff1a;2、验证函数生成值3、获取 年月日时分秒 的全随机4、时间函数 前言&#xff1a;有时候我们做性能测试或者接口测试时&#xff0c;参数需要传入日期格式&#xff0c;但是又不想每次都是用同一个日期&#xff0c;我们就可以使用Jmeter工具中函数助手…

2024050702-重学 Java 设计模式《实战状态模式》

重学 Java 设计模式&#xff1a;实战状态模式「模拟系统营销活动&#xff0c;状态流程审核发布上线场景」 一、前言 写好代码三个关键点 如果把写代码想象成家里的软装&#xff0c;你肯定会想到家里需要有一个非常不错格局最好是南北通透的&#xff0c;买回来的家具最好是品…

Mysql 中的case-when

什么是 case-when case-when 是一种 sql 语句中的语法结构,结构如下&#xff1a; case 字段名 when 值 then 字段名|值 ... else 字段名|值 end case when 主要用于数据的 行列转换&#xff08;把一列数据转换为多列&#xff09; 前置条件&#xff1a; -- 表…

02.体验CSS以及Bootstrap框架

目录 CSS固定格式 1&#xff09;style标签 2&#xff09;div标签 3&#xff09;span标签 CSS属性 一、文字属性 1.规范文字样式的属性 2.规定文字粗细的属性 3.规定文字大小的属性 4.规范文字字体的属性 二、文本属性 1.文本装饰属性 2.文本水平对齐属性 3.文本缩进…

[flutter]一键将YAPI生成的api.json文件转为需要的Dart Model类的脚本

目的&#xff1a; 根据YAPI接口平台生成的api.json接口文件&#xff0c;将接口数据转化为model类&#xff0c;生成对应的接口值类型文件。 发现&#xff1a; api.json文件导出&#xff1a; YAPi是一个接口管理平台&#xff0c;登录账号打开项目后&#xff0c;在点击数据管理…

Vuex3学习笔记

文章目录 1&#xff0c;入门案例辅助函数 2&#xff0c;mutations传参辅助函数 3&#xff0c;actions辅助函数 4&#xff0c;getters辅助函数 5&#xff0c;模块拆分6&#xff0c;访问子模块的state辅助函数 7&#xff0c;访问子模块的getters辅助函数 8&#xff0c;访问子模块…

Python魔法之旅-魔法方法(23)

目录 一、概述 1、定义 2、作用 二、应用场景 1、构造和析构 2、操作符重载 3、字符串和表示 4、容器管理 5、可调用对象 6、上下文管理 7、属性访问和描述符 8、迭代器和生成器 9、数值类型 10、复制和序列化 11、自定义元类行为 12、自定义类行为 13、类型检…

【Python】数据处理:OS目录文件操作

Python的os模块是一个用于与操作系统进行交互的标准库模块。它提供了丰富的功能来处理文件和目录、执行系统命令、获取和设置环境变量等。 工作目录操作 获取当前工作目录 os.getcwd()参数&#xff1a;无返回值&#xff1a;一个字符串&#xff0c;表示当前工作目录的路径。这…

什么,一不小心打造了一个基于大模型的操作系统

如果以大模型为Kernel, 形成一个新的操作系统&#xff0c;那么&#xff1a; 1. byzer-llm 是这个大模型操作系统的编程接口&#xff0c;有点类似Linux操作系统的C ABI。 2. byzer-retrieval 也被集成进 byzer- llm 接口里&#xff0c;算是大模型操作系统的文件系统&#xff0c…

pytorch 自定义学习率更新 Poly

Poly 学习率调整策略需要继承_LRScheduler类&#xff0c;该类包含三个重要属性和两个重要方法 学习率与batch-size的关系 一般来说&#xff0c;batch-size的大小一般与学习率的大小成正比。batch-size越大一般意味着算法收敛方向的置信度越大&#xff0c;也可以选择较大的学…

STM32快速入门(ADC数模转换)

STM32快速入门&#xff08;ADC数模转换&#xff09; 前言 ADC数模转换存在的意义就是将一些温度传感器、各自数据传感器产生的模拟信号转换成方便识别和计算的数字信号。 导航 图24 通用定时器框图&#xff1a; 图片截取自STM32 F1XX中文参考手册。还是以框图为中心&#x…

FinalShell导出服务器配置信息密码password是加密的,如何解密?

本章教程,主要实现了一个小的功能,对FinalShell导出的配置信息,进行解密。 FinalShell导出之后,会产生一个json文件,例如下面这种json格式,里面记录了服务器的IP地址,端口和密码,里面的密码是经过加密处理的,本文主要利用java代码实现对这个password进行解密还原。 {&…