成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專(zhuān)欄INFORMATION COLUMN

使用Vue的HOC技術(shù)開(kāi)發(fā)一個(gè)無(wú)限加載列表

stefan / 1384人閱讀

摘要:高階組件的概念,是里面經(jīng)常提到的,類(lèi)似于高階函數(shù)。高階函數(shù)高階組件高階組件用是代碼復(fù)用的優(yōu)秀工具,主要在處理邏輯方面和普適性上,有著奇效。

前言

在web開(kāi)發(fā)上,我們都對(duì)數(shù)據(jù)采用分頁(yè)加載的機(jī)制,一種變形就是在頁(yè)面采用循環(huán)加載的機(jī)制,拉到頁(yè)面最下方有個(gè)加載更多的按鈕。問(wèn)題在于,當(dāng)不同的數(shù)據(jù)要展示時(shí),就要寫(xiě)很多這種列表,但是其中的邏輯都是相似的。

維護(hù)一組數(shù)據(jù)

加載更多數(shù)據(jù)

將數(shù)據(jù)用對(duì)應(yīng)的組件顯示出來(lái)

處理加載狀態(tài)等

那有沒(méi)有這么一個(gè)組件,來(lái)完成這一切相同的邏輯呢?

需求

需要有這么一個(gè)InfiniteList組件,它負(fù)責(zé)管理相關(guān)數(shù)據(jù)的加載和維護(hù),然后以列表的形式顯示出來(lái),而列表項(xiàng)必須是由調(diào)用方?jīng)Q定的組件。

HOC

高階組件的概念,是React里面經(jīng)常提到的,類(lèi)似于高階函數(shù)。
高階函數(shù):(fn) => otherFn
高階組件:component => otherComponent
高階組件用是代碼復(fù)用的優(yōu)秀工具,主要在處理邏輯方面和普適性上,有著奇效。

所以我決定用HOC來(lái)實(shí)現(xiàn)這個(gè)需求

參考文章:http://hcysun.me/2018/01/05/%...
良心博客
本文涉及的知識(shí)

vue

vue的render函數(shù)

實(shí)現(xiàn) 0

我使用的是vue和iview UI庫(kù)

1

先弄出UI框架先,我用一個(gè)vue文件來(lái)構(gòu)建整個(gè)組件的基本框架。源代碼地址

html部分

用一個(gè)slot來(lái)分發(fā)要循環(huán)渲染的項(xiàng)目

js部分

一些UI有關(guān)的數(shù)據(jù)(不是很重要)

 props: {
      loadTip: {
        type: String,
        default: "加載更多"
      }
      ...
    },
    computed: {
      loadButtonText() {},
      tipIcon() {}
    }

這部分比較重要的只有一個(gè)事件發(fā)射,將點(diǎn)按鈕的行為轉(zhuǎn)換為 請(qǐng)求加載數(shù)據(jù)

handleClickLoad() {
        // 發(fā)射 請(qǐng)求加載數(shù)據(jù)的 事件
        this.$emit("on-load");
      }

css部分略

2

接下來(lái)就是最重要的部分,編寫(xiě)HOC
首先要明白,Vue中的組件,到底是什么。像我們寫(xiě)一個(gè)Vue文件,export出的是一個(gè)對(duì)象,所以我們現(xiàn)在寫(xiě)HOC,其實(shí)也是要最后返回一個(gè)對(duì)象。
所以我寫(xiě)了下面的函數(shù)來(lái)生成HOC

/**
 * 使用高階組件的辦法實(shí)現(xiàn)了一個(gè)無(wú)限加載列表
 * 可以根據(jù)數(shù)據(jù)循環(huán)渲染出特定的組件,并且管理加載狀態(tài)
 * @param component 具體項(xiàng)的組件 {props: {data}}
*/
function InfiniteList(listItem) {
    return {
        props:...
        data(){}
        ...
    }
}

而我們?nèi)绻秩灸?,?dāng)然是用Vue的render函數(shù)

render(h) {
    return h(component, data, children);
}

我們使用組合的方式,最外層需要用到我們第1步寫(xiě)到的模板,于是導(dǎo)入它,并注冊(cè)它

import InfiniteListTemplate from "./InfiniteListTemplate";
function InfiniteList(listItem) {
    return {
        ...
        components: {
          InfiniteListTemplate  //  列表框架的模板,這個(gè)模板里面只有ui表現(xiàn)
        },
        ...
    }
}

render函數(shù)對(duì)于熟悉React的程序員來(lái)說(shuō)應(yīng)該是不難的,官網(wǎng)也有很詳細(xì)的介紹。

render(h) {
      const self = this;
      // 根據(jù) data 的 dataList循環(huán)渲染子組件
      const listItems = ...

      return h(InfiniteListTemplate, {
        props: {
          ...self.$props, // 傳遞所有參數(shù)
          hasMore: self.hasMore,  // 另外的hasMore和loading是這個(gè)HOC的state
          loading: self.loading
        },
        attrs: self.$attrs,
        on: {
          // 監(jiān)聽(tīng)加載按鈕事件
          "on-load": () => self.handleLoadData()
        }
      }, listItems);
    },

這里在最外層渲染我們的模板(且稱(chēng)為模板組件),并將當(dāng)前HOC的props,attrs傳遞給模板組件。
這里提到了HOC的data,非常簡(jiǎn)單,就是兩個(gè)狀態(tài)和一個(gè)數(shù)據(jù)數(shù)組

data() {
      return {
        hasMore: true,
        loading: false,
        dataList: []
      }
    }

然后呢,循環(huán)渲染在哪?別急,render中的listItems就是我們循環(huán)渲染出來(lái)的組件,這里使用了map,相信使用React的人非常熟悉這種風(fēng)格

const listItems = this.dataList.map(item => h(component, {
            props: {
              data: item
            }
          })
        );

最終返回的就是

return h(InfiniteListTemplate, {options}, listItems);

在哪里維護(hù)數(shù)據(jù)呢?當(dāng)然是要傳入一個(gè)加載數(shù)據(jù)的函數(shù)來(lái)進(jìn)行管理,我們?cè)贖OC的props里面定義

props: {
      tipColor,
      loadTip,
      loadingTip,
      // 上面的數(shù)據(jù)都是為了傳給模板(組件)
      offset: {
        type: Number,
        default: 5
      },
      // 數(shù)據(jù)加載的函數(shù),需要的是一個(gè) (index, offset) => Promise<[]>
      loadDataFunc: {
        type: Function,
        default() {
          return (index, offset) => Promise.resolve(new Array(offset).map((o, i) => index + i));
        }
      }
    },

然后我們還記得模板函數(shù)發(fā)射了個(gè)on-load事件么?我們需要在HOC里監(jiān)聽(tīng)它并且處理邏輯

render(h) {
    return h(InfiniteListTemplate, {
        ...
        on: {
            "on-load": () => self.handleLoadData()
        }
    }, listItems);
},
methods: {
      /**
       * 監(jiān)聽(tīng)模板點(diǎn)出了加載按鈕時(shí)的操作
       * 調(diào)用數(shù)據(jù)加載函數(shù)加載數(shù)據(jù)
       * @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}條新數(shù)據(jù)`);
          } else {
            this.$Message.info(`已經(jīng)獲取了全部數(shù)據(jù)了`);
            this.hasMore = false;
          }
        } catch (e) {
          this.$Message.error("加載失敗" + e.message);
        } finally {
          this.loading = false;
        }
      }
    },

完整InfiniteList.js代碼

3

接下來(lái)使用一遍



MyComponent.vue是個(gè)非常簡(jiǎn)單的組件



效果圖如下

總結(jié)

在前端開(kāi)發(fā)過(guò)程中,HOC是代碼利用的利器,但是對(duì)抽象的要求高。
我覺(jué)得自己愛(ài)上了React...Vue實(shí)現(xiàn)這個(gè)HOC煩死了

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/100857.html

相關(guān)文章

  • 02.react進(jìn)階指南

    摘要:指定讀取當(dāng)前的。它為其后代元素觸發(fā)額外的檢查和警告。嚴(yán)格模式檢查僅在開(kāi)發(fā)模式下運(yùn)行它們不會(huì)影響生產(chǎn)構(gòu)建。作用識(shí)別不安全的生命周期關(guān)于使用過(guò)時(shí)字符串的警告關(guān)于使用廢棄的方法的警告檢測(cè)意外的副作用檢測(cè)過(guò)時(shí)的為高階組件。 react 進(jìn)階 懶加載 React.lazy函數(shù)能讓你像渲染常規(guī)組件一樣處理動(dòng)態(tài)引入(的組件)。Suspense加載指示器為組件做優(yōu)雅降級(jí)。fallback屬性接受任何在...

    zzbo 評(píng)論0 收藏0
  • 基于 Vue.js 移動(dòng)端組件庫(kù)mint-ui實(shí)現(xiàn)無(wú)限滾動(dòng)加載更多

    摘要:網(wǎng)上找到很多的組件來(lái)實(shí)現(xiàn)上拉加載更多,由于上拉觸發(fā)相應(yīng)的加載更多事件,所以當(dāng)進(jìn)入頁(yè)面的時(shí)候應(yīng)該不會(huì)自動(dòng)載入數(shù)據(jù),則這里可以加一個(gè)獲取第一頁(yè)數(shù)據(jù)的函數(shù)。 通過(guò)多次爬坑,發(fā)現(xiàn)了這些監(jiān)聽(tīng)滾動(dòng)來(lái)加載更多的組件的共同點(diǎn), 因?yàn)檫@些加載更多的方法是綁定在需要加載更多的內(nèi)容的元素上的, 所以是進(jìn)入頁(yè)面則直接觸發(fā)一次,當(dāng)監(jiān)聽(tīng)到滾動(dòng)事件之后,繼續(xù)加載更多, 所以對(duì)于無(wú)限滾動(dòng)加載不需要寫(xiě)首次載入列表的函數(shù)...

    huayeluoliuhen 評(píng)論0 收藏0
  • React 328道最全面試題(持續(xù)更新)

    摘要:希望大家在這浮夸的前端圈里,保持冷靜,堅(jiān)持每天花分鐘來(lái)學(xué)習(xí)與思考。 今天的React題沒(méi)有太多的故事…… 半個(gè)月前出了248個(gè)Vue的知識(shí)點(diǎn),受到很多朋友的關(guān)注,都強(qiáng)烈要求再出多些React相前的面試題,受到大家的邀請(qǐng),我又找了20多個(gè)React的使用者,他們給出了328道React的面試題,由我整理好發(fā)給大家,同時(shí)發(fā)布在了前端面試每日3+1的React專(zhuān)題,希望對(duì)大家有所幫助,同時(shí)大...

    kumfo 評(píng)論0 收藏0
  • 可靠React組件設(shè)計(jì)7個(gè)準(zhǔn)則之SRP

    摘要:編寫(xiě)組件時(shí)要考慮的基本準(zhǔn)則是單一職責(zé)原則。這些更改通常要求組件在隔離狀態(tài)下易于修改這也是的目標(biāo)。解決多重責(zé)任問(wèn)題需要將分割為兩個(gè)組件和。組件之間的通信是通過(guò)實(shí)現(xiàn)。更改的唯一原因是修改表單字段。 翻譯:劉小夕原文鏈接:https://dmitripavlutin.com/7-... 原文的篇幅非常長(zhǎng),不過(guò)內(nèi)容太過(guò)于吸引我,還是忍不住要翻譯出來(lái)。此篇文章對(duì)編寫(xiě)可重用和可維護(hù)的React組...

    Charles 評(píng)論0 收藏0
  • 使用Vue2+webpack+Es6快速開(kāi)發(fā)一個(gè)移動(dòng)端項(xiàng)目,封裝屬于自己jsonpAPI和手勢(shì)響應(yīng)

    摘要:導(dǎo)語(yǔ)最近看到不少使用制作的音樂(lè)播放器,挺好玩的,本來(lái)工作中也經(jīng)常使用,一起交流學(xué)習(xí),好的話(huà)點(diǎn)個(gè)哦本項(xiàng)目特點(diǎn)如下原生封裝自己的跨域請(qǐng)求函數(shù),支持調(diào)用,支持錯(cuò)誤處理制作一些復(fù)用性強(qiáng)的組件,如輪播圖組件,支持手勢(shì)滑動(dòng),無(wú)限循環(huán),圖片按需加載 showImg(http://upload-images.jianshu.io/upload_images/4149586-1849aa83e2decf...

    lemanli 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<