0

0

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

不言

不言

发布时间:2019-01-10 11:11:47

|

3767人浏览过

|

来源于segmentfault

转载

本篇文章给大家带来的内容是关于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部分

用一个slot来分发要循环渲染的项目

  • js部分

一些UI有关的数据(不是很重要)

魔法映像企业网站管理系统
魔法映像企业网站管理系统

技术上面应用了三层结构,AJAX框架,URL重写等基础的开发。并用了动软的代码生成器及数据访问类,加进了一些自己用到的小功能,算是整理了一些自己的操作类。系统设计上面说不出用什么模式,大体设计是后台分两级分类,设置好一级之后,再设置二级并选择栏目类型,如内容,列表,上传文件,新窗口等。这样就可以生成无限多个二级分类,也就是网站栏目。对于扩展性来说,如果有新的需求可以直接加一个栏目类型并新加功能操作

下载
 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}
       */
      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

接下来使用一遍



MyComponent.vue是个非常简单的组件



效果图如下

3073855418-5c34b708b68da_articlex.png

总结

在前端开发过程中,HOC是代码利用的利器,但是对抽象的要求高。
我觉得自己爱上了React...Vue实现这个HOC烦死了

相关专题

更多
css
css

css是层叠样式表,用来表现HTML或XML等文件样式的计算机语言,不仅可以静态地修饰网页,还可以配合各种脚本语言动态地对网页各元素进行格式化。php中文网还为大家带来html的相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

522

2023.06.15

css居中
css居中

css居中:1、通过“margin: 0 auto; text-align: center”实现水平居中;2、通过“display:flex”实现水平居中;3、通过“display:table-cell”和“margin-left”实现居中。本专题为大家提供css居中的相关的文章、下载、课程内容,供大家免费下载体验。

262

2023.07.27

css如何插入图片
css如何插入图片

cssCSS是层叠样式表(Cascading Style Sheets)的缩写。它是一种用于描述网页或应用程序外观和样式的标记语言。CSS可以控制网页的字体、颜色、布局、大小、背景、边框等方面,使得网页的外观更加美观和易于阅读。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

753

2023.07.28

css超出显示...
css超出显示...

在CSS中,当文本内容超出容器的宽度或高度时,可以使用省略号来表示被隐藏的文本内容。本专题为大家提供css超出显示...的相关文章,相关教程,供大家免费体验。

539

2023.08.01

css字体颜色
css字体颜色

CSS中,字体颜色可以通过属性color来设置,用于控制文本的前景色,字体颜色在网页设计中起到很重要的作用,具有以下表现作用:1、提升可读性;2、强调重点信息;3、营造氛围和美感;4、用于呈现品牌标识或与品牌形象相符的风格。

757

2023.08.10

什么是css
什么是css

CSS是层叠样式表(Cascading Style Sheets)的缩写,是一种用于描述网页(或其他基于 XML 的文档)样式与布局的标记语言,CSS的作用和意义如下:1、分离样式和内容;2、页面加载速度优化;3、实现响应式设计;4、确保整个网站的风格和样式保持统一。

604

2023.08.10

css三角形怎么写
css三角形怎么写

CSS可以通过多种方式实现三角形形状,本专题为大家提供css三角形怎么写的相关教程,大家可以免费体验。

560

2023.08.21

css设置文字颜色
css设置文字颜色

CSS(层叠样式表)可以用于设置文字颜色,这样做有以下好处和优势:1、增加网页的可视化效果;2、突出显示某些重要的信息或关键字;3、增强品牌识别度;4、提高网页的可访问性;5、引起不同的情感共鸣。

389

2023.08.22

Golang gRPC 服务开发与Protobuf实战
Golang gRPC 服务开发与Protobuf实战

本专题系统讲解 Golang 在 gRPC 服务开发中的完整实践,涵盖 Protobuf 定义与代码生成、gRPC 服务端与客户端实现、流式 RPC(Unary/Server/Client/Bidirectional)、错误处理、拦截器、中间件以及与 HTTP/REST 的对接方案。通过实际案例,帮助学习者掌握 使用 Go 构建高性能、强类型、可扩展的 RPC 服务体系,适用于微服务与内部系统通信场景。

4

2026.01.15

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 3.6万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 2.2万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 2.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号