【new IntersectionObserver】vue3 数据懒加载

new IntersectionObserver js方法描述步骤

实现逻辑:通过监视底部节点可视情况,获取新数据进行渲染,如果获取不到最新数据则显示暂无其他数据

new IntersectionObserver 是用于监视元素可见度,所以我们只需要监视数据下方的dom是否可见

先在hook文件下封装useIntersectionObserver方法

import { type Ref, watchEffect, ref } from "vue"

//我用的ts,不需要可以删除
interface IntersectionObserverProps {
  target: Ref<Element | null | undefined>
  root?: Ref<any>
  onIntersect: IntersectionObserverCallback
  rootMargin?: string
  threshold?: number | number[]
}

export function useIntersectionObserver({ target, root, onIntersect, rootMargin = "0px", threshold = 0.1 }: IntersectionObserverProps) {
  let cleanup: Function//每次调用前先移除监听
  const observer: Ref<Nullable<IntersectionObserver>> = ref(null)
  const stopEffect = watchEffect(() => {
    cleanup && cleanup()

    observer.value = new IntersectionObserver(onIntersect, {
      root: root ? root.value : null,//设置监视器的根节点,不传则默认为视口
      rootMargin,//类似于 CSS 的 margin 属性。用来缩小或扩大 rootBounds,从而影响相交的触发。
      threshold/*属性决定相交比例为多少时,触发回调函数。取值为 0 ~ 1,或者 0 ~ 1的数组。
		当我们把  threshold 设置为 [0, 0.25, 0.5, 0.75, 1],
		元素分别在 0%,25%,50%,75%,100% 可见时,触发回调函数。*/
    })

    const current = target.value//被监视的元素本身

    current && observer.value.observe(current)// 开始观察某个目标元素

    cleanup = () => {
      if (observer.value) {
        observer.value.disconnect()// 关闭监视器
        target.value && observer.value.unobserve(target.value)// 停止观察某个目标元素
      }
    }
  })
  //将方法暴露出来外部也可使用
  return {
    observer,
    stop: () => {
      cleanup()
      stopEffect()
    }
  }
}

不清楚方法配置项的可以看MDN Intersection Observer

组件中使用
暂无其他数据的dom给到方法去监视

这里我只是简单演示方法,监视效果达后到可以自行更改ui触底后的逻辑

在这里插入图片描述
html部分

<div v-for='item in data' key='item' >{{item}}</div>
<div  ref="empty">{{"暂无其他数据" }}</div>

js部分

const empty = ref(null)
// 默认在初始创建节点时会触发一次,因为初始没有数据节点会在视图中完整呈现,也可以让节点在有数据的时候再创建
const { stop, observer } = useIntersectionObserver({
  target: empty,//最底部的dom
  onIntersect: (entries: any[]) => {//isIntersecting:boolean 表示节点是否可见,intersectionRatio:number 表示节点可见度数值
    const isIntersecting = entries[0].isIntersecting || entries[0].intersectionRatio
    if (!isIntersecting) return
    
    ... //此处写要实现的逻辑
  
  },
  threshold: 0.1//为1 表示dom完整呈现
})

如果需要详细讲解可以看这两篇文章:

https://juejin.cn/post/6844903927419256846
https://juejin.cn/post/6950464500491354126#heading-9

也可以去MDN Intersection Observer 查看完整配置项和方法

vue基于组合式API提供的@vueuse/core插件内的useIntersectionObserver

  1. 安装
    npm i @vueuse/core

  2. 使用
    useIntersectionObserver其实就是方便了我们之前封装的那个步骤,如果想要基于这个二次封装也是可以的

// 封装一个通用的方法实现数据的懒加载
import { useIntersectionObserver } from '@vueuse/core'
import { ref } from 'vue'

export const useLazyData = (apiFn) => {
  // target表示组件的最外层div元素
  const target = ref(null)
  // 懒加载接口返回的数据
  const result = ref([])
  // 监听组件是否进入可视区
  const { stop } = useIntersectionObserver(target, ([{ isIntersecting }]) => {
    // 如果target对应的DOM进入可视区,那么该回调函数就触发
    if (isIntersecting) {
      // 被监听的DOM进入了可视区:此时调用接口获取数据;停止继续监听
      stop()
      
      ... //此处写要实现的逻辑

    }
  })
  // result表示接口懒加载获取的业务数据
  // target表示被监听的DOM元素,需要在模板中被ref属性绑定
  return { result, target }
}

详细可看官网介绍https://www.vueusejs.com/core/useIntersectionObserver/

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值