vue3 - 使用IntersectionObserver实现懒加载
1. 基础用法
<script setup lang="ts"> import { ref, onMounted, onUnmounted } from 'vue' // loading-image const imgUrl = ref(new URL('/src/assets/loading.png', import.meta.url).href) let observer: IntersectionObserver onMounted(() => { // 注册观察者 observer = new IntersectionObserver(entries => { for (let index = 0; index < entries.length; index++) { // 获取到目标元素img标签 const target = entries[index].target as HTMLImageElement // 观察者返回的对象 const element = entries[index] if (element.isIntersecting) { target.src = target.dataset.src ?? '' observer && observer.unobserve(target) } } }) // 遍历所有class为lazy-image的图片 const imgs: HTMLCollection = document.getElementsByClassName('lazy-image') for (const img of Array.from(imgs)) { img && observer.observe(img) } // 断开所有观察 onUnmounted(() => { observer.disconnect() }) }) </script> <template> <div class="card" v-for="item in 10" :key="item"> <img class="lazy-image" data-src="https://qtfei.com/images/logo.jpg" :src="imgUrl" alt="某网站logo" /> </div> </template> <style scoped> .read-the-docs { color: #888; } .card { padding: 200px; } </style>
2. 自定义一个简单的懒加载指令
main.ts
import { createApp } from 'vue' import './style.css' import App from './App.vue' import lazyload from './directives/lazyload' createApp(App) .directive('lazyload', lazyload) .mount('#app')
Vue template
<img v-lazyload="'https://qtfei.com/images/logo.jpg'" :src="imgUrl" alt="某网站logo" />
lazyload.ts
let observer: IntersectionObserver function _observer (el: HTMLImageElement, src: string) { observer = new IntersectionObserver(entries => { for (let index = 0; index < entries.length; index++) { // 获取到目标元素img标签 const target = entries[index].target as HTMLImageElement // 观察者返回的对象 const element = entries[index] if (element.isIntersecting) { console.log('显示了') target.src = src || '' observer && observer.unobserve(target) } } }) observer.observe(el) } export default { mounted (el: HTMLImageElement, binding: any, vnode: any) { _observer(el, binding.value) }, unmounted (el: HTMLImageElement) { observer.disconnect() } }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析