React和Vue中暴露子組件的屬性和方法給父組件用,并且控制子組件暴露的顆粒度的做法

React

在 React 中,forwardRef 是一種高級技術,它允許你將 ref 從父組件傳遞到子組件,從而直接訪問子組件的 DOM 節點或公開的方法。這對于需要操作子組件內部狀態或 DOM 的場景非常有用。為了使子組件能夠暴露其屬性和方法給父組件,通常會結合 useImperativeHandle Hook 使用 forwardRef

如何使用 forwardRefuseImperativeHandle

  1. 創建一個帶有 forwardRef 的子組件:

    • 使用 React.forwardRef 來創建一個接受 ref 參數的組件。
  2. 使用 useImperativeHandle 定義要暴露的方法和屬性:

    • 在子組件中使用 useImperativeHandle 來定義哪些方法或屬性應該通過 ref 暴露出去。
  3. 在父組件中使用 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 定義了 focusInputgetInputValue 方法,并將它們綁定到傳入的 ref 上。這意味著父組件可以通過 ref 訪問這些方法。
  • 父組件 (ParentComponent.js):

    • 創建了一個 ref (childComponentRef) 并將其傳遞給 ChildComponent
    • 提供了兩個按鈕,分別用于調用子組件的 focusInputgetInputValue 方法。

這種方法確保了父組件可以安全地與子組件進行交互,同時保持良好的封裝性。通過 useImperativeHandle,你可以精確控制哪些方法或屬性是公開的,而不會意外地暴露不必要的實現細節。

Vue

當你通過 ref 獲取到子組件的根 DOM 元素后,你可以使用標準的 DOM API 來訪問或操作該元素及其子元素。如果你想要訪問 <p> 標簽,可以通過多種方式實現,具體取決于你想要進行的操作。

訪問子元素的方法

  1. 使用 querySelectorquerySelectorAll:

    • 這些方法允許你根據選擇器(如標簽名、類名、ID 等)來查找特定的子元素。
  2. 遍歷子節點:

    • 你可以使用 childrenchildNodes 或其他類似屬性來遍歷子節點。
  3. 直接訪問特定子元素:

    • 如果你知道子元素的具體位置,可以直接通過 firstElementChildlastElementChild 等屬性訪問。

示例代碼

假設你想在父組件中訪問并打印子組件中的 <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 的響應式系統內,這樣可以使應用更加高效和易于維護。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/62886.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/62886.shtml
英文地址,請注明出處:http://en.pswp.cn/web/62886.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

《C++ 實時視頻流物體跟蹤與行為分析全解析》

在當今科技飛速發展的時代&#xff0c;視頻監控與智能分析技術在眾多領域發揮著極為重要的作用。從安防監控到智能交通&#xff0c;從工業自動化到人機交互&#xff0c;利用 C 處理實時視頻流中的物體跟蹤和行為分析成為了熱門且極具挑戰性的研究與開發方向。本文將深入探討其中…

5G中的隨機接入過程可以不用收RAR?

有朋友提到了一種不用接收RAR的RA過程&#xff0c;問這個是怎么回事。其實在剛剛寫過的LTM cell switch篇章中就有提到&#xff0c;這里把所有相關的內容整理如下。 在RACH-less LTM場景&#xff0c;在進行LTM cell switch之前就要先知道target cell的TA信息&#xff0c;進而才…

git 導出某段時間修改的文件 windows

第一步&#xff1a;列出兩次commitID之間的文件變動 git diff oldid newid --name-only// 例如 git diff 4a886c57a8b5611a2abcfcd120461c2e92f7029a HEAD --name-only 4a886c57a8b5611a2abcfcd120461c2e92f7029a 代表之前 HEAD 代表最新或者換成某次commitID 例如&#xf…

Qt 聯合Halcon配置

文章目錄 配置代碼窗口綁定 配置 選擇添加庫 選擇外部庫 LIBS -LC:/Program Files/MVTec/HALCON-17.12-Progress/lib/x64-win64/ LIBS -lhalconcpp\-lhdevenginecpp\-lhalconINCLUDEPATH C:/Program Files/MVTec/HALCON-17.12-Progress/include DEPENDPATH C:/Program Fil…

new URL(`../assets/images/${name}`, import.meta.url).href

背景&#xff1a; 文章講述了Vite框架中關于資源文件&#xff08;如圖片&#xff09;在默認配置下&#xff0c;如何正確處理開發環境和打包后的不同引用方式。重點介紹了使用import.meta.url和new URL() 來動態獲取并處理靜態資源URL的方法&#xff0c;以及注意事項&#xff0…

8、筆記本品牌分類介紹:LG - 計算機硬件品牌系列文章

LG筆記本品牌以其高性能和先進技術而聞名&#xff0c;?提供多種型號以滿足不同用戶的需求。? LG筆記本產品線包括多種類型&#xff0c;?以滿足不同用戶的需求。?其中&#xff0c;?LG Gram Pro系列以其超薄設計和高性能配置受到關注。?該系列筆記本采用16:10的OLED顯示屏&…

367_C++_計算mouse移動過程中,視頻框的右側、底部邊距,以及根據實時的右側、底部邊距計算—視頻框的左上角位置

代碼分析 1. restorePos 方法 restorePos 的作用是恢復 NavigationFrame 的位置,將其移動到父窗口或者指定矩形內的特定位置。 void NavigationFrame::restorePos() {// 獲取目標矩形:優先使用 `m_pRect`,否則默認使用視頻區域或父窗口區域RSRect videoRect(m_pVide

Tiptap,: 富文本編輯器入門與案例分析

Tiptap 是一個現代的富文本編輯器&#xff0c;基于 ProseMirror 打造&#xff0c;旨在提供一個靈活且功能強大的文本編輯解決方案。它具有開箱即用的能力&#xff0c;同時也允許開發者根據業務需求進行高度定制化擴展。與傳統的富文本編輯器相比&#xff0c;Tiptap 提供了更精細…

scala的泛型類

泛型&#xff1a;類型參數化 泛型類指的是把泛型定義到類的聲明上, 即:該類中的成員的參數類型是由泛型來決定的. 在創建對象時, 明確具體的數據類型. 定義格式: class 類名&#xff08;成員名&#xff1a;數據類型&#xff09; class 類名[泛型名](成員名:泛型名) 參考代…

對比損失(Contrastive Loss)與大模型:Contrastive Loss and Large Models (中英雙語)

對比損失&#xff08;Contrastive Loss&#xff09;與大模型&#xff1a;從原理到實踐 在現代深度學習中&#xff0c;對比損失&#xff08;Contrastive Loss&#xff09;是一種核心技術&#xff0c;尤其是在對比學習&#xff08;Contrastive Learning&#xff09;中被廣泛使用…

Java基礎學習:java常用啟動命令

一、java -jar 1、系統屬性傳遞 使用形式&#xff1a;java -DpathD:\jacoco -jar 獲取方式&#xff1a;System.getProperties() 2、系統參數傳遞 使用形式&#xff1a;java -jar application.jar --jacocoPathD:\tomcat 獲取方式&#xff1a;通過啟動方法入口main的參數arg…

Linux下SVN客戶端保存賬號密碼

參考文章&#xff1a;解決&#xff1a;Linux上SVN 1.12版本以上無法直接存儲明文密碼_linux svn 保存密碼-CSDN博客新版本svn使用gpg-agent存儲密碼-CSDN博客svn之無法讓 SVN 存儲密碼&#xff0c;即使配置設置為允許_編程設計_ITGUEST 方法一&#xff1a;明文方式保存密碼 首…

負載均衡oj項目:介紹

目錄 項目介紹 項目演示 項目介紹 負載均衡oj是一個基于bs模式的項目。 用戶使用瀏覽器向oj模塊提交代碼&#xff0c;oj模塊會在所有在線的后端主機中選擇一個負載情況最低的主機&#xff0c;將用戶的代碼提交給該主機&#xff0c;該主機進行編譯運行&#xff0c;將結果返回…

gateway 微服務的入口-筆記

本文屬于b站圖靈課堂springcloud筆記系列。講的好還不要錢&#xff0c;值得推薦。 為什么需要API網關&#xff1f; 客戶端多次請求不同的微服務&#xff0c;會增加客戶端代碼和配置的復雜性&#xff0c;維護成本比價高認證復雜&#xff0c;每個微服務可能存在不同的認證方式&…

vue2+element-ui實現多行行內表格編輯

效果圖展示 當在表格中點擊編輯按鈕時:點擊的行變成文本框且數據回顯可以點擊確定按鈕修改數據或者取消修改回退數據: 具體實現步驟 1. 行數據定義編輯標記 行數據定義編輯標記 當在組件中獲取到用于表格展示數據的方法中,針對每一行數據添加一個編輯標記 this.list.f…

安卓主板_MTK聯發科android主板方案

在當前智能設備的發展中&#xff0c;安卓主板的配置靈活性和性能優化顯得尤為重要。安卓主板的聯發科方案&#xff0c;在芯片上&#xff0c;搭載聯發科MTK6761、MT8766、MT6765、MT6762、MT8768、MT8390、MTK8370以及MT8788等型號&#xff0c;均基于64位的四核或八核架構設計。…

如何破解“不會寫作”的煩惱

在人生的諸多煩惱中&#xff0c;有一種煩惱或許不那么顯眼&#xff0c;卻常常如影隨形&#xff0c;讓人倍感困擾——那就是不會寫作的煩惱。這不僅僅是對那些以寫作為生的人而言&#xff0c;對于每一個需要在學習、工作或生活中以文字表達思想、情感的人來說&#xff0c;不會寫…

虛幻5描邊輪廓材質

很多游戲內都有這種描邊效果&#xff0c;挺實用也挺好看的&#xff0c;簡單復刻一下 效果演示&#xff1a; Linethickness可以控制輪廓線條的粗細 這樣連完&#xff0c;然后放到網格體細節的覆層材質上即可 可以自己更改粗細大小和顏色

修改docker源

在/etc/docker/daemon.json文件中寫入 { "registry-mirrors": [ "Welcome to nginx!" ] } 執行 systemctl daemon-reload systemctl restart docker docker info能夠看到源已經被替換 現在國內能夠使用的docker源經過測試只有Welcome to nginx! …

【JavaEE】網絡(2)

一、網絡編程套接字 1.1 基礎概念 【網絡編程】指網絡上的主機&#xff0c;通過不同的進程&#xff0c;以編程的方式實現網絡通信&#xff1b;當然&#xff0c;我們只要滿足進程不同就行&#xff0c;所以即便是同一個主機&#xff0c;只要是不同進程&#xff0c;基于網絡來傳…