亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

利用Vue中HOC技術開發一個無限加載列表的方法

發布時間:2020-08-28 10:02:08 來源:億速云 閱讀:258 作者:小新 欄目:web開發

利用Vue中HOC技術開發一個無限加載列表的方法?這個問題可能是我們日常學習或工作經常見到的。希望通過這個問題能讓你收獲頗深。下面是小編給大家帶來的參考內容,讓我們一起來看看吧!

在web開發上,我們都對數據采用分頁加載的機制,一種變形就是在頁面采用循環加載的機制,拉到頁面最下方有個加載更多的按鈕。問題在于,當不同的數據要展示時,就要寫很多這種列表,但是其中的邏輯都是相似的。

  1. 維護一組數據

  2. 加載更多數據

  3. 將數據用對應的組件顯示出來

  4. 處理加載狀態等

那有沒有這么一個組件,來完成這一切相同的邏輯呢?

需求

需要有這么一個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部分

<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>

用一個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<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}條新數據`);
          } else {
            this.$Message.info(`已經獲取了全部數據了`);
            this.hasMore = false;
          }
        } catch (e) {
          this.$Message.error("加載失敗" + e.message);
        } finally {
          this.loading = false;
        }
      }
    },

完整InfiniteList.js代碼

3

接下來使用一遍

<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是個非常簡單的組件

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

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

效果圖如下

利用Vue中HOC技術開發一個無限加載列表的方法

在前端開發過程中,HOC是代碼利用的利器,但是對抽象的要求高。
我覺得自己愛上了React...Vue實現這個HOC煩死了

感謝各位的閱讀!看完上述內容,你們對利用Vue中HOC技術開發一個無限加載列表的方法大概了解了嗎?希望文章內容對大家有所幫助。如果想了解更多相關文章內容,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

长顺县| 涟源市| 台南县| 绥宁县| 宝兴县| 南阳市| 双江| 富顺县| 繁昌县| 达日县| 乌拉特中旗| 贵德县| 阜阳市| 仁化县| 板桥市| 新绛县| 汤阴县| 九龙县| 尼木县| 吐鲁番市| 辽阳市| 商都县| 交城县| 石城县| 宁乡县| 永丰县| 东丽区| 临夏县| 安仁县| 长泰县| 永安市| 海林市| 淮北市| 喀什市| 昭平县| 巴彦县| 三台县| 南康市| 绵竹市| 昔阳县| 常德市|