欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

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

利用Vue中HOC技術(shù)開(kāi)發(fā)一個(gè)無(wú)限加載列表的方法?這個(gè)問(wèn)題可能是我們?nèi)粘W(xué)習(xí)或工作經(jīng)常見(jiàn)到的。希望通過(guò)這個(gè)問(wèn)題能讓你收獲頗深。下面是小編給大家?guī)?lái)的參考內(nèi)容,讓我們一起來(lái)看看吧!

成都創(chuàng)新互聯(lián)2013年開(kāi)創(chuàng)至今,是專(zhuān)業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目做網(wǎng)站、成都網(wǎng)站建設(shè)網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個(gè)夢(mèng)想脫穎而出為使命,1280元連平做網(wǎng)站,已為上家服務(wù),為連平各地企業(yè)和個(gè)人服務(wù),聯(lián)系電話(huà):18982081108

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

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

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

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

  4. 處理加載狀態(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部分

<template>
  <div class="wrapper">
    <div class="content-wrapper">
      <slot></slot>
    </div>
    <div class="load-wrapper">
      <Button
        :icon="tipIcon"
        type="text"
        v-bind:disabled="!hasMore"
        v-bind:style="{color: tipColor}"
        v-bind:loading="loading"
        v-on:click="handleClickLoad">
        {{loadButtonText}}
      </Button>
    </div>
  </div>
</template>

用一個(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<void>}
       */
      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)使用一遍

<script>
import MyComponent from "./components/MyComponent";
import InfiniteList from "./components/hoc/InfiniteList";
const InfiniteListComponent = InfiniteList(MyComponent);
...

data() {
    loadDataFunc: (index, offset) => Promise<[]>
}
</script>

<template>
  <div id="app">
    <InfiniteListComponent
      v-if="loadDataFunc"
      v-bind:load-data-func="loadDataFunc">
    </InfiniteListComponent>
  </div>
</template>

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

<template>
  <div>Hello</div>
</template>

<script>
  export default {
    name: "MyComponent",
    props: {
      data: {
        type: String
      }
    }
  }
</script>

效果圖如下

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

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

感謝各位的閱讀!看完上述內(nèi)容,你們對(duì)利用Vue中HOC技術(shù)開(kāi)發(fā)一個(gè)無(wú)限加載列表的方法大概了解了嗎?希望文章內(nèi)容對(duì)大家有所幫助。如果想了解更多相關(guān)文章內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。

分享文章:利用Vue中HOC技術(shù)開(kāi)發(fā)一個(gè)無(wú)限加載列表的方法
瀏覽路徑:http://chinadenli.net/article14/gphjde.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供響應(yīng)式網(wǎng)站標(biāo)簽優(yōu)化定制開(kāi)發(fā)做網(wǎng)站網(wǎng)站維護(hù)網(wǎng)站營(yíng)銷(xiāo)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都seo排名網(wǎng)站優(yōu)化