Vue3列表触底请求(上手体验hooks新特性)

今天我们来聊一聊业务开发中的触底请求,其实就是分页的一种,只不过传统的分页感觉很丑而已,正好我的小博客最近在做触底分页,借此机会来说一说具体怎么实现的,以及来带领大家使用一下Vue3中的新特性hooks函数。

案例和我实际开发的功能会有差异,这里我只是想讲明白具体的思路。

一、触底分页思路

我这里就列举我自己实现的这种方式把,就是通过监听scroll,通过对比滚动卷入的高度(scrollTop)、窗口的高度(clientHeight)和滚动条的总高度(scrollHeight)三者之间插值的计算,来判断是否发起请求。

后续你可能还会判断:如果数据库没有更多的数据我们就不再请求等操作(这里我就不过多讲解了)。

二、Hooks函数

在 Vue 3 中,引入了 Composition API,它是一种新的 API 设计范式,为我们提供了更加灵活和可组合的代码组织方式。使我们的代码写起来更加的舒服,我们今天就来使用一下其中的一个重要概念Hooks

首先Hooks 是一种函数,以 use 开头,用于封装可复用的逻辑。它们提供了一种在函数组件中复用状态逻辑的方式,使我们能够更好地组织组件代码,将相关的逻辑聚合在一起,实现更高水平的可维护性。

借用知乎大佬的定义:集成定义一些可复用的方法,可以随时被引入和调用以实现高内聚低耦合的目标,应该都能算是hook。

下面我们就结合Hook函数,一起来实现一下触底功能。

三、Hooks具体实现

大家会学到两部分,触底的实现思路和hooks的使用。

3.1 创建文件

src 目录下创建 hooks/usePagination.js ,抛出一个函数,我们的所有业务都放在此函数中,并且通过 return 进行返回,我们会使用到一些 Vue钩子(ref, onMounted等),通过 import 进行导入。

import {ref, onMounted, onUnmounted } from 'vue'

export const usePagination = () => {

    return {
        ...
    }
}

3.2 编写触底业务函数

这里我用到了三个自己定义的变量loadingcurrentPagelist

  • loading:作用类似于节流,防止我们重复触底,重复请求;
  • currentPage:就是当前页码(默认为1);
  • list:来存储我们http请求的数据。

我们通过setTimeout来模拟一下http请求。

const loading = ref(false)
const loading = ref(false)
const list = ref([])

const scrollBottom = () => {
    // 判断是否在请求阶段
    if(loading.value) return
    // 获取滚动条卷入的高度
    let scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
    // 获取可视区的高度
    let windowHeight = document.documentElement.clientHeight || document.body.clientHeight;
    // 获取滚动条的总高度
    let scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight;
    
    if (scrollTop + windowHeight >= scrollHeight) {
        console.log('开始请求');
        loading.value = true;
        currentPage.value ++
        setTimeout(() => {
            loading.value = false
            // http请求函数
            getList(currentPage.value)
        }, 2000)   
    }
}

3.3 http请求函数

请求函数接收两个参数,当前页和每次请求的条数,这个我通过for循环pushlist中来模拟。

const getList = (currentPage = 1, currentSize = 10) => {
    for (let i = 0; i < currentSize; i ++) {
        list.value.push({
            id: new Date().getTime(),
        })
    }
    console.log(list.value)
}

3.4 挂载触底函数

当我们组件加载/注销完成之后挂载/卸载我们的触底函数。

onMounted(() => {
    console.log('事件已挂载');
    window.addEventListener('scroll', scrollBottom);
    getList();
})

onUnmounted(() => {
    console.log('事件已移除');
    window.removeEventListener('scroll', scrollBottom);
})

3.5 return数据

返回我们在组件中需要用到的变量函数

export const usePagination = () => {
    ...
    ...
    
    return {
        currentPage,
        list,
        getList
    }
}

3.6 完整代码

import { ref, onMounted, onUnmounted } from 'vue'  

export const usePagination = () => {
    const currentPage = ref(1)
    const list = ref([])
    const loading = ref(false)
    // 判断触底
    const scrollBottom = () => {
        if(loading.value) return
        let scrollTop = document.documentElement.scrollTop || document.body.scrollTop

        // 变量 windowHeight 是可视区的高度
        let windowHeight =
document.documentElement.clientHeight || document.body.clientHeight
        // 变量 scrollHeight 是滚动条的总高度
        let scrollHeight =
document.documentElement.scrollHeight || document.body.scrollHeight  

        if (scrollTop + windowHeight >= scrollHeight) {
            console.log('开始请求');
            loading.value = true
            currentPage.value ++
            setTimeout(() => {
                loading.value = false
                getList(currentPage.value)
            }, 2000)
        }
    }  

    // 请求数据
    const getList = (currentPage = 1, currentSize = 10) => {
        console.log(currentPage)
        for (let i = 0; i < currentSize; i ++) {
            list.value.push({
                id: new Date().getTime(),
            })
        }
    }

    onMounted(() => {
        console.log('事件已挂载');
        window.addEventListener('scroll', scrollBottom)
        getList()
    })

    onUnmounted(() => {
        console.log('事件已移除');
        window.removeEventListener('scroll', scrollBottom)
    })

    return {
        currentPage,
        list,
        getList
    }
}

四、组件使用

4.1 编写组件模板

我们编写一个列表来渲染我们的list数组

<template>
    <div class="container">
        <div class="item" v-for="(item, index) in list" :key="item.id">
            我是列表内容{{ index + 1 }}
        </div>
    </div>
</template>

<style lang="scss" scoped>
.container {
    display: flex;
    flex-direction: column;
    align-items: center;
    
    .item {
        width: 60%;
        height: 150px;
        border: 1px solid #000;
        margin-bottom: 10px;
    }
}
</style>

4.1 引入

通过import导入hook函数,执行hook函数,解构出我们需要的值,如果对解构不太了解的小伙伴,可以看我往期的文章,勇宝趣学JavaScript ES6第二章(解构赋值)

<script setup>
import { usePagination } from '@/hooks/usePagination';

const { currentPage, list } = usePagination();

</script>

五、效果

效果图晚点时间给小伙伴们呈现,在外边,这台笔记本没有做gif的工具,先放一个静态的图片给大家泄泄火把

4.PNG

六、总结

今天给大家讲解了一下触底的实现过程以及 Vue3 中hooks的上手体验,希望大家会对 Vue3 有一个更加深刻的认识。

说实话我写不出那些高大上的代码,哈哈哈,希望大家能理解我这个前端小菜鸟。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/414356.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

uniapp小程序uView自定义tabbar

两年没接触小程序&#xff0c;又重新拾请来 前言 工具&#xff1a;HBuilder X 3.99版本 微信开发者工具 1.06 语言&#xff1a;vue2 uView 一、创建项目 先使用HBuilder X工具创建一个空白uni-app项目 uviewTest 二、安装和配置 HBuilder X找到工具-》插件安装-》插件市场 u…

Flutter中高级JSON处理:使用json_serializable进行深入定制

Flutter中高级JSON处理 使用json_serializable库进行深入定制 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at: https://jclee95.blog.csdn.netEmail: 291148484163.com. Shenzhen ChinaAddress of this article:https://blog.csdn.net/qq_28550263/article/details/1363…

vscode不能远程连接ubuntu18.04.6

目录 问题解决Portable Mode 安装vscode 补充说明学习资料 问题 vscode远程ssh连接ubuntu18.04.6时&#xff0c;出现如下提示框&#xff0c;单击Learn More后&#xff0c;定位到问题。Can I run VS Code Server on older Linux distributions? 原始是&#xff1a;需要glibc …

Mac 配置Clion Qt 调试显示变量值

背景 使用Clion开发Qt程序&#xff0c;在进行调试时&#xff0c;会看不到Qt类的变量值&#xff0c;只有指针形式&#xff0c;对于调试很不方便。 环境&#xff1a; Macbook ProCPU&#xff1a;M3Qt 5.15.13CLion 2023.3.4 解决方案 为了让Clion能显示Qt类的值&#xff0c;…

Ubuntu常用状态命令

目录 一、温度 1&#xff0c;查看CPU温度 2&#xff0c;查看硬盘温度 二、CPU状态 1&#xff0c;显示CPU的详细信息&#xff0c;包括型号、频率、缓存等 2&#xff0c;显示CPU架构、CPU核心数、线程数、频率等信息 三、登录状态 1&#xff0c;查看成功登录的用户 2&am…

4核8g服务器能支持多少人访问?

腾讯云4核8G服务器支持多少人在线访问&#xff1f;支持25人同时访问。实际上程序效率不同支持人数在线人数不同&#xff0c;公网带宽也是影响4核8G服务器并发数的一大因素&#xff0c;假设公网带宽太小&#xff0c;流量直接卡在入口&#xff0c;4核8G配置的CPU内存也会造成计算…

【代码解读】OpenCOOD框架之model模块(以PointPillarFCooper为例)

point_pillar_fcooper PointPillarFCooperPointPillarsPillarVFEPFNLayerPointPillarScatterBaseBEVBackboneDownsampleConvDoubleConv SpatialFusion检测头 &#xff08;紧扣PointPillarFCooper的框架结构&#xff0c;一点一点看代码&#xff09; PointPillarFCooper # -*- c…

在两台CentOS 7服务器上部署MinIO集群---准确

环境说明&#xff1a; 2台Centos7服务器 IP地址分别为172.16.1.9和172.16.1.10 1. 创建minio用户和目录 在两台服务器上执行以下命令&#xff1a; sudo useradd -m -d /app/minio minio sudo mkdir -p /app/minioData sudo mkdir -p /app/minio/logs sudo chown -R mini…

数据结构与算法(数组,栈,队列,链表,哈希表,搜索算法,排序算法,查找算法,策略算法,递归算法,二叉搜索树BST,动态规划算法)

文章目录 1 课程介绍1.1 前置知识1.2 为什么要学习算法1.3 大厂面试常见数据结构题目(基础)1.4 数据结构和算法的关系 2 数据结构2.1 数据结构概述2.1.1 数据结构是什么2.1.2 数据结构分类2.1.2.1 线性结构2.1.2.2 非线性结构2.1.2.3 小总结 2.1.3 数据结构范围 2.2 数组Array2…

leetcode 2.27

leetcode hot 100 哈希1.字母异位词分组2.最长连续序列 双指针1.盛最多水的容器2.和为 K 的子数组 数组1.除自身以外数组的乘积 哈希 1.字母异位词分组 49. 字母异位词分组 方法一&#xff1a;排序 由于互为字母异位词的两个字符串包含的字母相同&#xff0c;因此对两个字符…

Redis之一: 简介及环境安装搭建

什么是NoSQL? NoSQL&#xff0c;指的是非关系型的数据库。NoSQL有时也称作Not Only SQL的缩写&#xff0c;是对不同于传统的关系型数据库的数据库管理系统的统称。 NoSQL用于超大规模数据的存储。&#xff08;例如谷歌或Facebook每天为他们的用户收集万亿比特的数据&#xf…

python:时间序列谐波拟合与残差分析(利用最小二乘法确定模型参数)

作者&#xff1a;CSDN _养乐多_ 在科学研究中&#xff0c;经常需要对实验数据进行拟合&#xff0c;以找出其中的规律。本文介绍了如何使用Python中的NumPy、Matplotlib和SciPy库进行谐波拟合&#xff0c;并对拟合结果进行残差分析。 从下图可以看出&#xff0c;谐波拟合曲线…

Python算法100例-2.6 分糖果

完整源代码项目地址&#xff0c;关注博主私信源代码后可获取 1.问题描述2.问题分析3.算法设计4.确定程序框架5.完整的程序6.运行结果 1&#xff0e;问题描述 10个小孩围成一圈分糖果&#xff0c;老师分给第1个小孩10块&#xff0c;第2个小孩2块&#xff0c;第3个小孩8块&…

C#,弗洛伊德-瑞文斯特(Floyd-Rivest)算法与源代码

Robert W. Floyd 1 Floyd-Rivest 算法 Floyd-Rivest 算法是一种选择算法&#xff0c;用于在不同元素的数组中找到第k个最小元素。它类似于快速选择算法&#xff0c;但在实际运行中有更好的运行时间。 和 QuickSelect 一样&#xff0c;该算法基于分区的思想工作。对数组进行分…

istio学习记录——VirtualService详解

上一篇使用VirtualService进行了简单的流量控制&#xff0c;并通过Gateway将流量导入到了集群内。这一篇将更加深入的介绍 VirtualService。 k8s中有service&#xff0c;service能够对流量进行负载均衡&#xff0c;那为什么istio又引入了VirtualService呢&#xff0c;因为serv…

最新IE跳转Edge浏览器解决办法(2024.2.26)

最新IE跳转Edge浏览器解决办法&#xff08;2024.2.26&#xff09; 1. IE跳转原因1.1. 原先解决办法1.2. 最新解决办法1.3. 最后 1. IE跳转原因 关于IE跳转问题是由于在2023年2月14日&#xff0c;微软正式告别IE浏览器&#xff0c;导致很多使用Windows10系统的电脑在打开IE浏览…

300分钟吃透分布式缓存-17讲:如何理解、选择并使用Redis的核心数据类型?

Redis 数据类型 首先&#xff0c;来看一下 Redis 的核心数据类型。Redis 有 8 种核心数据类型&#xff0c;分别是 &#xff1a; & string 字符串类型&#xff1b; & list 列表类型&#xff1b; & set 集合类型&#xff1b; & sorted set 有序集合类型&…

多线程与高并发(1)- 线程基础、并发特性、锁、JUC工具

文章目录 第一章、线程基础知识一、基础概念1、什么是程序&#xff1f;2、什么是进程&#xff1f;3、什么是线程&#xff1f;4、什么是线程的切换&#xff08;Context Switch&#xff09;&#xff1f;5、单核CPU 设定多线程是否有意义&#xff1f;6、工作线程数是不是设置的越大…

【Linux】部署单机项目(自动化启动)---(图文并茂详细讲解)

目录 一 准备工作 1.1 连接服务器拷贝文件 1.2 解压 二 JDK安装 2.1 配置坏境变量 2.2 查看版本 三 Tomcat(自启动) 3.1 复制启动命令的位置 3.2 添加命令相关配置文件 3.2.1 配置jdk及tomcat目录 3.2.2 添加优先级 3.3 设置自启动命令 3.4 开放端口 四 My…

行业交流 | “建筑工业化—创新型建筑技术的应用”主题沙龙

11月9日下午&#xff0c;由环同济知识经济圈发展推进领导小组办公室指导&#xff0c;上海市杨浦区科委、同济科技园核心园、同济EMBA设计协会联合主办&#xff0c;环同济发展促进会协办的“建筑工业化——创新型建筑技术的应用”主题沙龙在我园区顺利举办。优积建筑科技发展(上…