這篇文章帶給大家的內容是關於Vue的HOC技術如何開發一個無限加載列表(程式碼範例),有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。
在web開發上,我們都對資料採用分頁載入的機制,一種變形就是在頁面採用循環載入的機制,拉到頁面最下方有個載入更多的按鈕。問題在於,當不同的數據要展示時,就要寫很多這種列表,但是其中的邏輯都是相似的。
維護一組資料
載入更多資料
將資料用對應的元件顯示出來
處理載入狀態等
那有沒有這麼一個元件,來完成這一切相同的邏輯呢?
需要有這麼一個InfiniteList元件,它負責管理相關資料的載入和維護,然後以清單的形式顯示出來,而清單項目必須是由呼叫方決定的元件。
高階元件的概念,是React裡面常提到的,類似高階函數。
高階函數:(fn) => otherFn
高階元件:component => otherComponent
高階元件用是程式碼重複使用的優秀工具,主要在處理邏輯方面和普適性上,有著奇效。
所以我決定用HOC來實現這個需求
參考文章:http://hcysun.me/2018/01/05/%...
良心部落格
vue
vue的render函數
<template> <div> <div> <slot></slot> </div> <div> <button> {{loadButtonText}} </button> </div> </div> </template>
props: { loadTip: { type: String, default: "加载更多" } ... }, computed: { loadButtonText() {}, tipIcon() {} }
handleClickLoad() { // 发射 请求加载数据的 事件 this.$emit("on-load"); }
首先要明白,Vue中的元件,到底是什麼。像我們寫一個Vue文件,export出的是一個對象,所以我們現在寫HOC,其實也是要最後回傳一個對象。
所以我寫了下面的函數來產生HOC
/** * 使用高阶组件的办法实现了一个无限加载列表 * 可以根据数据循环渲染出特定的组件,并且管理加载状态 * @param component 具体项的组件 {props: {data}} */ function InfiniteList(listItem) { return { props:... data(){} ... } }
render(h) { return h(component, data, children); }
import InfiniteListTemplate from "./InfiniteListTemplate"; function InfiniteList(listItem) { return { ... components: { InfiniteListTemplate // 列表框架的模板,这个模板里面只有ui表现 }, ... } }
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的data,非常簡單,就是兩個狀態和一個資料數組
data() { return { hasMore: true, loading: false, dataList: [] } }
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; } } },</void>
<script> import MyComponent from "./components/MyComponent"; import InfiniteList from "./components/hoc/InfiniteList"; const InfiniteListComponent = InfiniteList(MyComponent); ... data() { loadDataFunc: (index, offset) => Promise<[]> } </script> <template> <div> <infinitelistcomponent> </infinitelistcomponent> </div> </template>
#MyComponent .vue是個非常簡單的元件
<template> <div>Hello</div> </template> <script> export default { name: "MyComponent", props: { data: { type: String } } } </script>
總結在前端開發過程中,HOC是程式碼利用的利器,但是對抽象的要求高。
我覺得自己愛上了React...Vue實現這個HOC煩死了
以上是Vue的HOC技術如何開發一個無限載入清單(程式碼範例)的詳細內容。更多資訊請關注PHP中文網其他相關文章!