摘要:高階組件的概念,是里面經常提到的,類似于高階函數。高階函數高階組件高階組件用是代碼復用的優秀工具,主要在處理邏輯方面和普適性上,有著奇效。
前言
在web開發上,我們都對數據采用分頁加載的機制,一種變形就是在頁面采用循環加載的機制,拉到頁面最下方有個加載更多的按鈕。問題在于,當不同的數據要展示時,就要寫很多這種列表,但是其中的邏輯都是相似的。
維護一組數據
加載更多數據
將數據用對應的組件顯示出來
處理加載狀態等
那有沒有這么一個組件,來完成這一切相同的邏輯呢?
需求需要有這么一個InfiniteList組件,它負責管理相關數據的加載和維護,然后以列表的形式顯示出來,而列表項必須是由調用方決定的組件。
HOC高階組件的概念,是React里面經常提到的,類似于高階函數。
高階函數:(fn) => otherFn
高階組件:component => otherComponent
高階組件用是代碼復用的優秀工具,主要在處理邏輯方面和普適性上,有著奇效。
所以我決定用HOC來實現這個需求
參考文章:http://hcysun.me/2018/01/05/%...本文涉及的知識
良心博客
vue
vue的render函數
實現 0我使用的是vue和iview UI庫
1先弄出UI框架先,我用一個vue文件來構建整個組件的基本框架。源代碼地址
html部分
用一個slot來分發要循環渲染的項目
js部分
一些UI有關的數據(不是很重要)
props: { loadTip: { type: String, default: "加載更多" } ... }, computed: { loadButtonText() {}, tipIcon() {} }
這部分比較重要的只有一個事件發射,將點按鈕的行為轉換為 請求加載數據
handleClickLoad() { // 發射 請求加載數據的 事件 this.$emit("on-load"); }
css部分略
2接下來就是最重要的部分,編寫HOC
首先要明白,Vue中的組件,到底是什么。像我們寫一個Vue文件,export出的是一個對象,所以我們現在寫HOC,其實也是要最后返回一個對象。
所以我寫了下面的函數來生成HOC
/** * 使用高階組件的辦法實現了一個無限加載列表 * 可以根據數據循環渲染出特定的組件,并且管理加載狀態 * @param component 具體項的組件 {props: {data}} */ function InfiniteList(listItem) { return { props:... data(){} ... } }
而我們如果渲染呢,當然是用Vue的render函數
render(h) { return h(component, data, children); }
我們使用組合的方式,最外層需要用到我們第1步寫到的模板,于是導入它,并注冊它
import InfiniteListTemplate from "./InfiniteListTemplate"; function InfiniteList(listItem) { return { ... components: { InfiniteListTemplate // 列表框架的模板,這個模板里面只有ui表現 }, ... } }
render函數對于熟悉React的程序員來說應該是不難的,官網也有很詳細的介紹。
render(h) { const self = this; // 根據 data 的 dataList循環渲染子組件 const listItems = ... return h(InfiniteListTemplate, { props: { ...self.$props, // 傳遞所有參數 hasMore: self.hasMore, // 另外的hasMore和loading是這個HOC的state loading: self.loading }, attrs: self.$attrs, on: { // 監聽加載按鈕事件 "on-load": () => self.handleLoadData() } }, listItems); },
這里在最外層渲染我們的模板(且稱為模板組件),并將當前HOC的props,attrs傳遞給模板組件。
這里提到了HOC的data,非常簡單,就是兩個狀態和一個數據數組
data() { return { hasMore: true, loading: false, dataList: [] } }
然后呢,循環渲染在哪?別急,render中的listItems就是我們循環渲染出來的組件,這里使用了map,相信使用React的人非常熟悉這種風格
const listItems = this.dataList.map(item => h(component, { props: { data: item } }) );
最終返回的就是
return h(InfiniteListTemplate, {options}, listItems);
在哪里維護數據呢?當然是要傳入一個加載數據的函數來進行管理,我們在HOC的props里面定義
props: { tipColor, loadTip, loadingTip, // 上面的數據都是為了傳給模板(組件) offset: { type: Number, default: 5 }, // 數據加載的函數,需要的是一個 (index, offset) => Promise<[]> loadDataFunc: { type: Function, default() { return (index, offset) => Promise.resolve(new Array(offset).map((o, i) => index + i)); } } },
然后我們還記得模板函數發射了個on-load事件么?我們需要在HOC里監聽它并且處理邏輯
render(h) { return h(InfiniteListTemplate, { ... on: { "on-load": () => self.handleLoadData() } }, listItems); }, methods: { /** * 監聽模板點出了加載按鈕時的操作 * 調用數據加載函數加載數據 * @return {Promise} */ async handleLoadData() { try { this.loading = true; let res = await this.loadDataFunc(this.dataList.length, this.offset); if (res && res.length) { this.dataList = this.dataList.concat(res); this.$Message.success(`成功獲取到${res.length}條新數據`); } else { this.$Message.info(`已經獲取了全部數據了`); this.hasMore = false; } } catch (e) { this.$Message.error("加載失敗" + e.message); } finally { this.loading = false; } } },
完整InfiniteList.js代碼
3接下來使用一遍
MyComponent.vue是個非常簡單的組件
Hello
效果圖如下
在前端開發過程中,HOC是代碼利用的利器,但是對抽象的要求高。
我覺得自己愛上了React...Vue實現這個HOC煩死了
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/100857.html
摘要:指定讀取當前的。它為其后代元素觸發額外的檢查和警告。嚴格模式檢查僅在開發模式下運行它們不會影響生產構建。作用識別不安全的生命周期關于使用過時字符串的警告關于使用廢棄的方法的警告檢測意外的副作用檢測過時的為高階組件。 react 進階 懶加載 React.lazy函數能讓你像渲染常規組件一樣處理動態引入(的組件)。Suspense加載指示器為組件做優雅降級。fallback屬性接受任何在...
摘要:網上找到很多的組件來實現上拉加載更多,由于上拉觸發相應的加載更多事件,所以當進入頁面的時候應該不會自動載入數據,則這里可以加一個獲取第一頁數據的函數。 通過多次爬坑,發現了這些監聽滾動來加載更多的組件的共同點, 因為這些加載更多的方法是綁定在需要加載更多的內容的元素上的, 所以是進入頁面則直接觸發一次,當監聽到滾動事件之后,繼續加載更多, 所以對于無限滾動加載不需要寫首次載入列表的函數...
摘要:希望大家在這浮夸的前端圈里,保持冷靜,堅持每天花分鐘來學習與思考。 今天的React題沒有太多的故事…… 半個月前出了248個Vue的知識點,受到很多朋友的關注,都強烈要求再出多些React相前的面試題,受到大家的邀請,我又找了20多個React的使用者,他們給出了328道React的面試題,由我整理好發給大家,同時發布在了前端面試每日3+1的React專題,希望對大家有所幫助,同時大...
摘要:編寫組件時要考慮的基本準則是單一職責原則。這些更改通常要求組件在隔離狀態下易于修改這也是的目標。解決多重責任問題需要將分割為兩個組件和。組件之間的通信是通過實現。更改的唯一原因是修改表單字段。 翻譯:劉小夕原文鏈接:https://dmitripavlutin.com/7-... 原文的篇幅非常長,不過內容太過于吸引我,還是忍不住要翻譯出來。此篇文章對編寫可重用和可維護的React組...
摘要:導語最近看到不少使用制作的音樂播放器,挺好玩的,本來工作中也經常使用,一起交流學習,好的話點個哦本項目特點如下原生封裝自己的跨域請求函數,支持調用,支持錯誤處理制作一些復用性強的組件,如輪播圖組件,支持手勢滑動,無限循環,圖片按需加載 showImg(http://upload-images.jianshu.io/upload_images/4149586-1849aa83e2decf...
閱讀 1833·2021-11-25 09:43
閱讀 1335·2021-11-22 15:08
閱讀 3735·2021-11-22 09:34
閱讀 3225·2021-09-04 16:40
閱讀 3002·2021-09-04 16:40
閱讀 542·2019-08-30 15:54
閱讀 1335·2019-08-29 17:19
閱讀 1752·2019-08-28 18:13