IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> vue3.0项目中手动封装加载更多数据(常见) -> 正文阅读

[JavaScript知识库]vue3.0项目中手动封装加载更多数据(常见)

技术点 ?Vue官方工具库?(仅限vue3.0使用)中的?useIntersectionObserver??

使用场景:在一些购物平台中,往往都会看见下滑商品的时候当滑倒底部就会去请求最新的数据,和数据懒加载和图片懒加载很类似

?一、模拟数字实现

?默认数字为60个数字 当滚到第60个数字时模拟请求20个数字?

?封装组件

npm i @vueuse/core
<template>
  <div class="xtx-infinite-loading" ref="container">
    <!-- 正在加载数据时显示 -->
    <div class="loading" v-if="isLoading">
      <span class="img"></span>
      <span class="text">正在加载...</span>
    </div>
    <!-- 数据全部加载完毕时显示 -->
    <div class="none" v-if="isFinished">
      <span class="text">亲,没有更多了</span>
    </div>
  </div>
</template>
<script>
import { useIntersectionObserver } from '@vueuse/core'
import { ref } from 'vue'
export default {
  name: 'xtxInfiniteLoading',
  props: {
    // 是否在加载中
    isLoading: {
      type: Boolean,
      default: false
    },
    // 数据全部加载完毕
    isFinished: {
      type: Boolean,
      default: false
    }
  },
  setup (props, { emit }) {
    const container = ref(null)
    const { stop } = useIntersectionObserver(container, ([{ isIntersecting }]) => {
      if (isIntersecting) {
        // 双重 判断 缺一不可
        if (props.isFinished === false && props.isLoading === false) {
          emit('doLoading')
        }
      }
    })
    return { container, stop }
  }
}
</script>

<style scoped lang='less'>
.xtx-infinite-loading {
  .loading {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 200px;
    .img {
      width: 50px;
      height: 50px;
      background: url('~@/assets/images/load.gif') no-repeat center / contain;
    }
    .text {
      color: #999;
      font-size: 16px;
    }
  }
  .none {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 200px;
    .text {
      color: #999;
      font-size: 16px;
    }
  }
}
</style>

分析?

变量?
? ? isLoading?是否在加载中
??? isFinished?数据全部加载完毕

?DOM:

如果isLoading 为true 显示? 加载状态

如果?isFinished 为true? 显示 加载完毕

js :

要操作的DOM元素?

? const container = ref(null)

使用监听
? ? const { stop } = useIntersectionObserver(container, ([{ isIntersecting }]) => {

如果当前监听的元素可见
? ? ? if (isIntersecting) {
? ? ? ? // props传递时异步的? 双重 判断 缺一不可 当没有加载完毕 并且 没有正在加载??
? ? ? ? if (props.isFinished === false && props.isLoading === false) {

抛出事件给父组件
? ? ? ? ? emit('doLoading')
? ? ? ? }
? ? ? }
? ? })

测试

<template>
 <p v-for="i in list" :key="i" style="margin-left:50px"> {{i}} </p>
   <xtxInfiniteLoading @doLoading="doLoading" :isLoading="isLoading" :isFinished="isFinished"></xtxInfiniteLoading>
</template>
<script>
import { ref } from 'vue'
export default {
  setup () {
    const list = ref(60)
    const isLoading = ref(false)
    const isFinished = ref(false)
    const doLoading = () => {
      isLoading.value = true
      setTimeout(() => {
        list.value += 20
        isLoading.value = false
        if (list.value >= 100) {
          isFinished.value = true
        }
      }, 1000)
    }
    return { list, doLoading, isLoading, isFinished }
  }
}
</script>

?DOM:

循环list中的数据,并且接收子组件传过来的数据

JS

调用子组件抛出来的事件,加载完毕后把正在加载设为false? 当list数据大于等于100? 把加载完成设为true,也就是说当大于100的时候不再执行

? if (props.isFinished === false && props.isLoading === false) {? 子组件中判断如果加载和加载完毕都为false才执行
? ? ? ? ? emit('doLoading')
? ? ? ? }

项目中例子

封装的组件不用修改,直接在父组件中写代码

<template> 
<xtxInfiniteLoading @doLoading="doLoading" :isFinished="isFinished" :isLoading="isLoading" ></xtxInfiniteLoading>
</template>
<script>
import { ref } from 'vue'
export default {
  setup () {
    const isLoading = ref(false)
    const isFinished = ref(false)
    const doLoading = () => {
        isLoading.value = true
      findSubCategoryGoods(reqParams).then(res => {
        //思路①
        if (res.result.items.length) {
          isFinished.value = false
          reqParams.page++
        } else {
          isFinished.value = true
        }
        goodList.value.push(...res.result.items)

        //  思路②
        // isLoading.value = false
        // goodList.value.push(...res.result.items)
        // reqParams.page++
        // if (!res.result.items.length) {
        //   isFinished.value = true
        // }
      })
    }
      return {doLoading, isLoading, isFinished }
  }
}
</script>

?DOM:当浏览到可视区域 封装的子组件触发事件 给父组件? 父组件接受后就回去调用doLoading事件

JS: 触发doLoading事件

1.? 先把isLoading? 变量设为true代表正在加载?

2. 调用请求之后 if判断 如果返回的长度不为0 那么代表后台一直有数据?

3. if{? 把isLoading 状态改为false代表加载完了,页数++??}

4.else 代表后台的数据没有了 把isFinished 变量设为true 代表全部执行完了

5.每次调用函数 都把最新的数据添加到 goodList中 注意(一开始获取和添加不是同一个方法 只是同一个API

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-07-23 10:38:28  更:2021-07-23 10:38:38 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/6 8:32:52-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码