如何支持組件的子元素任意擺放

来源:https://www.cnblogs.com/apolis/archive/2020/04/01/12611249.html
-Advertisement-
Play Games

篩選組件包含一個 button 和一個 form,button 能控制 form 的顯示與隱藏。設計里 button 和 form 在一行,實現時理所當然地把這一行封裝成了一個組件。但在另一個項目里,設計有區別,button 被放到了面板的右上角,之前寫的組件沒法復用了。 ...


一個篩選組件如下圖:

filter bar component v1

篩選組件包含一個 button 和一個 formbutton 能控制 form 的顯示與隱藏。設計里 buttonform 在一行,實現時理所當然地把這一行封裝成了一個組件。

但在另一個項目里,設計有區別,button 被放到了面板的右上角,之前寫的組件沒法復用了。

filter bar component v2


看看之前封裝的組件:

function FilterBar() {
  const [showForm, setShowForm] = useState(true);

  return (
    <div className="container">
      <button
        onClick={() => setShowForm(pre => !pre)}
      >
        {showForm ? "<<< Filter" : "Filter >>>"}
      </button>
      {showForm && (
        <form>
          <label>
            Name <input />
          </label>
          <label>
            IP <input />
          </label>
        </form>
      )}
    </div>
  );
}

它做了以下 4 件事:

  1. 創建 button
  2. 創建 form
  3. 實現 buttonform 的聯動,
  4. 創建容器 div.container, 對 buttonform 佈局。

「創建容器 div.container, 對 buttonform 佈局」這件事導致了組件沒法在新項目里復用。


能不能寫一個組件,不對子元素佈局,把佈局的工作交給組件使用者去做?

思路:把 div.container 去掉,把 buttonform 的實例返回,組件變成了一個 hook。

function useFilterBar() {
  const [showForm, setShowForm] = useState(true);

  return [
    <button
      onClick={() => setShowForm(pre => !pre)}
    >
      {showForm ? "<<< Filter" : "Filter >>>"}
    </button>,
    showForm ? (
      <form>
        <label>
          Name <input />
        </label>
        <label>
          IP <input />
        </label>
      </form>
    ) : (
      undefined
    )
  ];
}
function App() {
  const [filterBtn, filterForm] = useFilterBar();

  return (
    <div className="card">
      <Header title="Users">{filterBtn}</Header>
      {filterForm}
      <table>
        <thead>
          <tr>
            <th>Name</th>
            <th>IP</th>
          </tr>
        </thead>
        <tbody>...</tbody>
      </table>
    </div>
  );
}

class 組件沒法用 hook 怎麼辦?

思路:使用高階組件,高階組件是函數組件,可以使用 hook,然後把 buttonform 通過 props 傳遞給 class 組件。

const withFilterBar = Cmp => props => {
  const [filterBtn, filterForm] = useFilterBar();

  return (
    <Cmp
      {...props}
      filterBtn={filterBtn}
      filterForm={filterForm}
    />
  );
};

我寫這篇文章的目的不是為了記錄技巧,而是希望對組件有新的思考:把「子元素關聯關係 - 邏輯」和「子元素佈局 - 視圖」兩件事拆開,讓組件更靈活。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 向組件中插入內容有2種方式 槽點 子組件 demo 使用槽點向組件中插入內容 Vue.component('Parent',{ template:` <!--反引號比引號更好用--> <div> <p>hello</p> <slot></slot> <!--如果後續要在組件中插入元素、內容,需要先留 ...
  • 如圖,想實現模糊查詢點擊文字賦值到搜索框,離開則關閉模糊查詢提示,但失去焦點時模糊查詢div隱藏就無法實現點擊賦值的事件了,這時候需要隱藏時判斷是否離開模糊查詢,附上代碼 //全局變數 var x,y; $(document).mousemove(function(e){ x = e.pageX; ...
  • [toc] 術語 1. web:互聯網。 2. w3c:萬維網聯盟,非盈利組織,官網:w3.org。為互聯網提供各種標準。 1. 代替網址:MDN:Mozilla Development Network。Mozilla開發者社區。有中文。 3. ISO:國際標準組織。 4. XML: 可擴展 的標記 ...
  • 很多讀者經常問我:愷哥,我怎麼樣才能進階前端呀?能推薦一些資料嘛? 首先我們定個基調,這裡的進階指的是讓自己成為厲害點的人,能夠找工作不難的人,相信大家都是想成為這樣的選手吧~ 其實大部分情況下你多學會了一門框架 / 庫的使用,或者多會了一門語言,確實能讓你做的事情更多了,但是離你真正實現技術進階還 ...
  • 將頁面拆分為多個組件,簡化了頁面開發,方便維護,組件也可以復用。 組件的類型 通用組件,比如表單、彈窗、菜單欄、分頁組件等 業務組件,實現某一業務的組件,比如抽獎組件 頁面組件,也叫做單頁,一個頁面就是一個組件,只完成功能,不復用 組件開發流程:聲明、註冊、使用 demo 組件使用流程 <div i ...
  • 按照國際慣例先放效果圖 項目結構搭建 首先修改app.vue <template> <div id="app"> <router-view/> </div> </template> <script> export default { name: 'App' } </script> <style> * ...
  • 前面業務里有個搜索功能 , 入口比較深 , 現在想要把入口挪到有公共header的地方 , 在不想完全實現一遍功能的情況下 , 就需要模擬進行多個點擊事件來執行點擊後的效果 執行先點擊1 ,再給inout賦值 ,再點擊2 基本思路是類似jquery的trigger方法 , 原生js也是可以實現 , ...
  • 1 完整代碼下載 https://pan.baidu.com/s/1JJyVcP2KqXsd5G6eaYpgHQ 提取碼 3fzt (壓縮包名: 2020-3-24-demo.zip) 2 圖片展示 3 主要代碼 布爾運算後的物體的幾何體會自動 導入到 幾何體列表選項中, 可自由選配材質 紋理 挺簡 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...