您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息
三六零分类信息网 > 三明分类信息网,免费分类信息发布

Vue的HOC技术如何开发一个无限加载列表(代码示例)

2025/11/21 12:44:54发布38次查看
本篇文章给大家带来的内容是关于vue的hoc技术如何开发一个无限加载列表(代码示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。
在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部分
<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>
效果图如下
总结在前端开发过程中,hoc是代码利用的利器,但是对抽象的要求高。
我觉得自己爱上了react...vue实现这个hoc烦死了
以上就是vue的hoc技术如何开发一个无限加载列表(代码示例)的详细内容。
三明分类信息网,免费分类信息发布

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录 Product