veu3组合式api结合vueUse的useIntersectionObserver实现el-table的某一列的数据请求的接口懒加载

业务需求

背景:

如上图所示,此el-table列表数据接口包含包括测试结束时间以及测试状态在内的数据,根据测试状态判定:1、非测试中:测试结束时间采用的是列表接口返回的测试结束时间数据。2、测试中:测试结束时间采用的是另外一个专门用来返回测试结束时间的携带每一条从行获取的参数的接口deadline接口的返回值

此时,如果不加以控制,再pagesize过大时,就会一次性请求太多次deadline接口。

所以,采用@vueuse/core 为我们提供的 useIntersectionObserver 方法,实现滚动到相应位置的可视区域时再请求可视区域的deadline接口

落地代码

@vueuse/core 为我们提供的 useIntersectionObserver 方法

0、安装vueUse:

npm i @vueuse/core

1、封装hooks   新建hooks.ts文件

import { useIntersectionObserver } from '@vueuse/core'
import { ref } from 'vue'
 
/**
 * 用于懒加载数据
 * @param {*} apiFn 懒加载数据的接口
 * @returns target: 需要绑定的DOM对象  result: 结果数据
 */
export const useLazyData = (apiFn) => {
  // 需要
  // 1. 被观察的对象
  // 2. 不同的API函数

  const target = ref(null)
  const result = ref([])
  const { stop } = useIntersectionObserver(
    target,
    ([{ isIntersecting }], observerElement) => {
      if (isIntersecting) {
        stop()
        // 调用API获取数据
        apiFn().then(data => {
          
            if(data){
                result.value = data.result

            }
        })
      }
    }
  )
  // 返回--->数据(dom,后台数据)
  return { target, result }
}

2、该表格列表的测试结束时间列采用了插槽

<el-table-column v-else-if="column.prop === 'end_time'" v-bind="column">
              <template v-slot="{ row }">
                <battaryLoading  :endTime="row.end_time" :modelValue="row" :class="['endTimeClass',endTimeBreathLight(row.end_time)]"></battaryLoading>
              </template>
 </el-table-column>

 3、直接进入battaryLoading  组件,绑定ref为target(如果没有封装组件就在需要懒加载的元素上绑定即可)

<template>
  <div>
    
    <!-- 测试中 state = 1 -->
    <section v-if="modelValue?.test_state === 1" ref="target">
      <!-- loading -->
      <section v-if="isLoading">
        <AppSvgIcon class="animate-spin h-20 w-20" iconName="icon-battery-loading"></AppSvgIcon>
        <span class="text-gray-700 text-14 ml-3">Loading</span>
      </section>
      <section v-else class="flex items-center">
        <span>{{ newData?.end_time }}</span> <span v-if="newData?.end_time" class="bg-[#FFF7ED] rounded text-[#EA580C] px-4 ml-5">预计</span>
      </section>
    </section>

    <!-- 非测试中 -->
    <section v-else>
      {{ $filters.formatDatetime(endTime) }}
    </section>
  </div>
</template>

4、引入封装的 useLazyData  hook

import { useLazyData } from './hook.ts'

5、封装api请求,并调用hook,传入api

//封装api
const payLoad = {
  //请求参数
}
const getDeadline = () => {
  return api('DataCheck/deadline')
    .test(payLoad, {
      showErrorMessage: false,
    })
    .then(([res]) => {
      if (res?.status === 200) {
        isLoading.value = false
        nextTick(() => {
          newData.value = { ...unref(newData), end_time: parseTime(res?.data?.Deadline) + '' }
        })
      } else {
        nextTick(() => {
          newData.value = { ...unref(newData), end_time: '' }
        })
      }
    })
    .catch(e => {
      console.error(e)
    })
    .finally(() => {
      setTimeout(() => {
        isLoading.value = false
      }, 3000)
    })
}

//解构出调用了hook并传了参数return出来的target, result
const { target, result } = useLazyData(getDeadline)

!!!注意:此时存在一个问题,当切换页码大小或者点击头部的刷新刷新表格数据,而非刷新浏览器时,表格不会再次刷新dom,useIntersectionObserver 不会再次执行

 解决方案:改变页码大小,刷新表格时强制刷新el-table的dom

 <el-table :key="tableKey"/>
//在刷新表格的方法中
 function handlerRefresh() {
      getTests()
      tableKey.value= +new Date()//改变key
    }
//在监听分页中
 watch([() => pagination.currentPage, () => pagination.pageSize], () => {
      getTests().then(() => {
      tableKey.value= +new Date()//改变key
      })
    })

参考:vue强制更新dom

参考: vue 第三方方法 useIntersectionObserver 实现数据懒加载_vue 懒加载第三方依赖_新时代农民工Top的博客-CSDN博客

此时就完美了,表格滚动条滚动到哪儿,需要懒加载的接口才会被触发

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值