React和Vue中暴露子组件的属性和方法给父组件用,并且控制子组件暴露的颗粒度的做法
React
在 React 中,forwardRef 是一种高级技术,它允许你将 ref 从父组件传递到子组件,从而直接访问子组件的 DOM 节点或公开的方法。这对于需要操作子组件内部状态或 DOM 的场景非常有用。为了使子组件能够暴露其属性和方法给父组件,通常会结合 useImperativeHandle Hook 使用 forwardRef。
如何使用 forwardRef 和 useImperativeHandle
-
创建一个带有
forwardRef的子组件:- 使用
React.forwardRef来创建一个接受ref参数的组件。
- 使用
-
使用
useImperativeHandle定义要暴露的方法和属性:- 在子组件中使用
useImperativeHandle来定义哪些方法或属性应该通过ref暴露出去。
- 在子组件中使用
-
在父组件中使用
ref来访问子组件的公开接口:- 创建一个
ref并将其传递给子组件,然后通过这个ref访问子组件暴露的方法或属性。
- 创建一个
示例代码
子组件 (ChildComponent.js)
import React, { useRef, useImperativeHandle, forwardRef } from 'react';const ChildComponent = forwardRef((props, ref) => {const inputRef = useRef(null);// 定义要暴露的方法useImperativeHandle(ref, () => ({focusInput: () => {inputRef.current.focus();console.log('子组件的输入框获得了焦点');},getInputValue: () => inputRef.current.value,}));return (<div><input ref={inputRef} type="text" placeholder="这是子组件的输入框" /></div>);
});export default ChildComponent;
父组件 (ParentComponent.js)
import React, { useRef } from 'react';
import ChildComponent from './ChildComponent';const ParentComponent = () => {const childComponentRef = useRef(null);const handleFocus = () => {if (childComponentRef.current) {childComponentRef.current.focusInput();}};const handleGetValue = () => {if (childComponentRef.current) {const value = childComponentRef.current.getInputValue();console.log('子组件的输入值:', value);}};return (<div><ChildComponent ref={childComponentRef} /><button onClick={handleFocus}>让子组件的输入框获得焦点</button><button onClick={handleGetValue}>获取子组件的输入值</button></div>);
};export default ParentComponent;
解释
-
子组件 (
ChildComponent.js):- 使用
forwardRef创建了一个接受ref参数的组件。 - 使用
useImperativeHandle定义了focusInput和getInputValue方法,并将它们绑定到传入的ref上。这意味着父组件可以通过ref访问这些方法。
- 使用
-
父组件 (
ParentComponent.js):- 创建了一个
ref(childComponentRef) 并将其传递给ChildComponent。 - 提供了两个按钮,分别用于调用子组件的
focusInput和getInputValue方法。
- 创建了一个
这种方法确保了父组件可以安全地与子组件进行交互,同时保持良好的封装性。通过 useImperativeHandle,你可以精确控制哪些方法或属性是公开的,而不会意外地暴露不必要的实现细节。
Vue
当你通过 ref 获取到子组件的根 DOM 元素后,你可以使用标准的 DOM API 来访问或操作该元素及其子元素。如果你想要访问 <p> 标签,可以通过多种方式实现,具体取决于你想要进行的操作。
访问子元素的方法
-
使用
querySelector或querySelectorAll:- 这些方法允许你根据选择器(如标签名、类名、ID 等)来查找特定的子元素。
-
遍历子节点:
- 你可以使用
children、childNodes或其他类似属性来遍历子节点。
- 你可以使用
-
直接访问特定子元素:
- 如果你知道子元素的具体位置,可以直接通过
firstElementChild、lastElementChild等属性访问。
- 如果你知道子元素的具体位置,可以直接通过
示例代码
假设你想在父组件中访问并打印子组件中的 <p> 标签的内容,可以按照以下方式修改你的代码:
子组件 (ChildComponent.vue)
<template><div ref="root"><p id="content">这是子组件的内容</p></div>
</template><script setup>
import { defineExpose, ref } from 'vue';const root = ref(null);// 使用 defineExpose 显式暴露给父组件的方法或属性
defineExpose({getRootEl: () => root.value,
});
</script>
父组件 (ParentComponent.vue)
<template><ChildComponent ref="childComponent" /><button @click="handleClick">点击我</button>
</template><script setup>
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';const childComponent = ref(null);const handleClick = () => {if (childComponent.value) {// 调用子组件的公开方法来获取 DOM 引用const el = childComponent.value.getRootEl();// 使用 querySelector 查找 <p> 标签const pElement = el.querySelector('p#content');console.log('子组件的 <p> 内容:', pElement?.textContent);}
};
</script>
解释
-
子组件 (
ChildComponent.vue):- 我们为
<p>标签添加了一个id="content",以便更容易地通过querySelector查找它。
- 我们为
-
父组件 (
ParentComponent.vue):- 在
handleClick方法中,我们首先调用getRootEl获取子组件的根元素。 - 然后,使用
querySelector方法通过 ID 选择器查找<p>标签,并打印其文本内容。这里使用了可选链操作符 (?.) 来安全处理可能为null的情况。
- 在
这种方法确保了你能够以一种安全且可控的方式访问子组件内部的特定 DOM 元素。请记住,尽量减少对 DOM 的直接操作,除非确实有必要。保持尽可能多的逻辑在 Vue 的响应式系统内,这样可以使应用更加高效和易于维护。
相关文章:
React和Vue中暴露子组件的属性和方法给父组件用,并且控制子组件暴露的颗粒度的做法
React 在 React 中,forwardRef 是一种高级技术,它允许你将 ref 从父组件传递到子组件,从而直接访问子组件的 DOM 节点或公开的方法。这对于需要操作子组件内部状态或 DOM 的场景非常有用。为了使子组件能够暴露其属性和方法给父组件…...
uniapp 常用的指令语句
uniapp 是一个使用 Vue.js 开发的跨平台应用框架,因此,它继承了 Vue.js 的大部分指令。以下是一些在 uniapp 中常用的 Vue 指令语句及其用途: v-if / v-else-if / v-else 条件渲染。v-if 有条件地渲染元素,v-else-if 和 v-else 用…...
python学opencv|读取图像(十四)BGR图像和HSV图像通道拆分
【1】引言 前序已经对BGR图像和HSV图像的转换进行了基本讨论,相关文章链接为: python学opencv|读取图像(十二)BGR图像转HSV图像-CSDN博客 python学opencv|读取图像(十三)BGR图像和HSV图像互相转换深入-C…...
C# 结构体和类
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、类(Class)二、结构体(Struct)示例代码(定义类和结构体)类的继承代码示例(…...
D9741是一块脉宽调制方三用于也收路像机和笔记本电的等设备上的直流转换器。在便携式的仪器设备上。
概述: D9741是一块脉宽调制方三用于也收路像机和笔记本电的等设备上的直流转换器。在便携式的仪器设备上。 主要特点: ● 高精度基准电路 ● 定时闩锁、短路保护电路 ● 低电压输入时误操作保护电路 ● 输出基准电压(2.5V) ● 超过工作范围能进行自动校…...
题目 1738: 排序
题目 1738: 排序 时间限制: 2s 内存限制: 96MB 提交: 14351 解决: 3477 题目描述 对输入的n个数进行排序并输出。 输入格式 输入的第一行包括一个整数n(1<n<100)。 接下来的一行包括n个整数。 输出格式 可能有多组测试数据,对于每组数据,将排序后…...
爬虫逆向学习(十四):分享一下某数通用破解服务开发经验
阅前须知 这篇博客不是教大家怎么实现的,而且告知大家有这个东西,或者说一种趋势,借此分享自己大致的实现经验。具体的实现我也不好整理,毕竟是在别人的基础上缝缝补补。 前言 使用补环境方式破解过某数的同学都知道࿰…...
《Vue进阶教程》第十一课:响应式系统介绍
1 什么是响应式 当数据改变时, 引用数据的函数会自动重新执行 2 手动完成响应过程 首先, 明确一个概念: 响应式是一个过程, 这个过程存在两个参与者: 一方触发, 另一方响应 比如说, 我们家小胖有时候不乖, 我会打他, 他会哭. 这里我就是触发者, 小胖就是响应者 同样, 所谓…...
rpc设计的再次思考20251215(以xdb为核心构建游戏框架)
1.服务提供者注册的方式 // 表明这是一个服务提供者,ServerType 和 ServerId从application.properties中读取 // 而且只有当当前服务是Game时,才生效。 或者 条件注解??? RpcProvider(typeServerType.Game) public class GameProvider{MsgReceiver…...
pydub AudioSegment增加音频文件音量并保存- python 实现
DataBall 助力快速掌握数据集的信息和使用方式,会员享有 百种数据集,持续增加中。 需要更多数据资源和技术解决方案,知识星球: “DataBall - X 数据球(free)” -------------------------------------------------------------…...
IT 新突破!远程控制电脑技术造就工作与学习新方向!
远程控制电脑技术的历史可追溯到计算机网络的早期时代。最初,通过电话线和调制解调器的组合,实现了远程访问,这是远程控制电脑技术的雏形。随着互联网技术的飞速发展,远程控制电脑技术也日趋完善,并在多个领域得到了广…...
LabVIEW起落架震台检测
在现代飞机制造与维护过程中,起落架的性能测试是保障飞机安全的重要环节。通过LabVIEW开发的起落架小落震台检测系统,通过模拟飞机着陆过程,准确捕捉起落架在着陆时承受的各种动力学特性和应力响应,有效提升起落架设计的精度与可靠…...
Day24 C++ 接口(抽象类)
C 接口(抽象类) 接口描述了类的行为和功能,而不需要完成类的特定实现。 C 接口是使用抽象类来实现的,抽象类与数据抽象互不混淆,数据抽象是一个把实现细节与相关的数据分离开的概念。 如果类中至少有一个函数被声明…...
UE5 关于画质、机能与开发成本的思考
1、并不省时间 UE5等工具优点是可以通过一些工具与资源快速获得较好的画面,节约一些时间, 但缺点也很多, 一个是各种精度的素材之间的协调问题,参差不齐,统一升级到高精度会产生较大的成本, 一个是资源…...
IOS学习路线图
iOS是由苹果公司开发的移动操作系统。 苹果公司最早于2007年1月9日的Macworld大会上公布这个系统,最初是设计给iPhone使用的,后来陆续套用到iPod touch、iPad上。iOS与苹果的macOS操作系统一样,属于类Unix的商业操作系统。原本这个系统名为…...
HICE-day6
二层交换 交换基础 所谓的二层交换机指的是针对数据的二层头部(以太网帧头)中的MAC地址进行寻址并转发数据的交换设备。二层交换机不具备路由功能,它工作在OSI七层模型的第二层,因此被称为二层交换机。 上图中,PC1、…...
第100+33步 ChatGPT学习:时间序列EMD-ARIMA-LSTM模型
基于Python 3.9版本演示 一、写在前面 上一节,我们学了经验模态分解(Empirical Mode Decomposition,EMD)。 如同结尾所说,“那么,做这些分解有什么作用呢?有大佬基于这些分解出来的序列分别作…...
(C语言)双向链表
目录 链表的分类 双向链表的实现 1)定义链表 2)初始化双向链表 3)申请节点 4)尾插 5)头插 6)打印链表 7)尾删 8)头插 9)查找 10)指定位置删除 11…...
青少年编程与数学 02-004 Go语言Web编程 04课题、接收和处理请求
青少年编程与数学 02-004 Go语言Web编程 04课题、接收和处理请求 课题摘要:一、构建WEB服务器1. 安装Go语言2. 创建项目结构3. 编写代码4. 运行WEB服务器5. 访问WEB服务器 二、接收请求1. 定义处理函数(Handler)2. 将处理函数与路由关联3. 启动服务器4. …...
Unity全局光照详解
之前就学过但是太久没用又忘了,因此用最简洁易懂的语言做个记录。 全局光照分为两个系统,分别是实时光照和混合光照。(点击window/Rendering/Lighing打开此面板) 其中全局光照对于我来说都是新技术了,上一次学…...
使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...
AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...
汽车生产虚拟实训中的技能提升与生产优化
在制造业蓬勃发展的大背景下,虚拟教学实训宛如一颗璀璨的新星,正发挥着不可或缺且日益凸显的关键作用,源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例,汽车生产线上各类…...
【决胜公务员考试】求职OMG——见面课测验1
2025最新版!!!6.8截至答题,大家注意呀! 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:( B ) A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...
【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)
本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...
虚拟电厂发展三大趋势:市场化、技术主导、车网互联
市场化:从政策驱动到多元盈利 政策全面赋能 2025年4月,国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》,首次明确虚拟电厂为“独立市场主体”,提出硬性目标:2027年全国调节能力≥2000万千瓦࿰…...
解读《网络安全法》最新修订,把握网络安全新趋势
《网络安全法》自2017年施行以来,在维护网络空间安全方面发挥了重要作用。但随着网络环境的日益复杂,网络攻击、数据泄露等事件频发,现行法律已难以完全适应新的风险挑战。 2025年3月28日,国家网信办会同相关部门起草了《网络安全…...
华为OD机试-最短木板长度-二分法(A卷,100分)
此题是一个最大化最小值的典型例题, 因为搜索范围是有界的,上界最大木板长度补充的全部木料长度,下界最小木板长度; 即left0,right10^6; 我们可以设置一个候选值x(mid),将木板的长度全部都补充到x,如果成功…...
