前端vue3實(shí)現(xiàn)圖片懶加載的完整步驟記錄
場(chǎng)景和指令用法
場(chǎng)景:電商網(wǎng)站的首頁(yè)通常會(huì)很長(zhǎng),用戶不一定能訪問(wèn)到頁(yè)面靠下面的圖片,這類圖片通過(guò)懶加載優(yōu)化手段可以做到只有進(jìn)入視口區(qū)域才發(fā)送圖片請(qǐng)求
核心原理:圖片進(jìn)入視口才發(fā)送資源請(qǐng)求

首先:我們需要定義一個(gè)全局的指令,vue3官方的實(shí)現(xiàn)方法是這樣的
第一步:熟悉指令語(yǔ)法

并且:還需要用到一個(gè)鉤子函數(shù)

第二步:判斷圖片是否進(jìn)入視口
我們可以使用useIntersectionObserver這個(gè)函數(shù)
以下是官方示例的使用方法:
<script setup lang="ts">
import { useIntersectionObserver } from '@vueuse/core'
const { stop } = useIntersectionObserver(
target,
([entry], observerElement) => {
targetIsVisible.value = entry?.isIntersecting || false
},
)
</script>target:需要監(jiān)聽的元素
isIntersecting:是一個(gè)布爾值 監(jiān)聽是否進(jìn)入可視區(qū)
以下是完整代碼實(shí)現(xiàn)
main.js
import { useIntersectionObserver } from '@vueuse/core'
const app = createApp(App)
// 定義全局指令
app.directive('img-lazy', {
mounted(el, binding) {
// el: 指令綁定的元素
// binding: binding.value 指令的綁定值 圖片url
console.log(el, binding.value);
useIntersectionObserver(
el, // 監(jiān)聽的元素
([{ isIntersecting }]) => {
// isIntersecting是一個(gè)布爾值 監(jiān)聽是否進(jìn)入可視區(qū)
console.log(isIntersecting);
if (isIntersecting) {
// 圖片進(jìn)入可視區(qū) 設(shè)置圖片的src
el.src = binding.value
}
}
)
}
})在需要懶加載的圖片標(biāo)簽里使用這個(gè)即可
<img v-img-lazy="item.picture" alt="" />
頁(yè)面效果

由上圖可以看出在剛進(jìn)入頁(yè)面時(shí)需要懶加載的圖片沒(méi)有加載出來(lái)

由上圖可以看出當(dāng)頁(yè)面滑動(dòng)到人氣推薦時(shí)url全部都加載出來(lái)了
回顧核心步驟代碼

================================補(bǔ)檔優(yōu)化==================================
問(wèn)題1:邏輯書寫位置不合理問(wèn):懶加載指令的邏輯直接寫到入口文件中,合理嗎?
答:不合理,入口文件通常只做一些初始化的事情,不該包含太多的邏輯代碼,可以通過(guò)插件的方法把懶加載指令封裝為插件,main.js入口文件只需要負(fù)責(zé)注冊(cè)插件即可

代碼實(shí)現(xiàn):
插件代碼

// 定義懶加載指令
import { useIntersectionObserver } from '@vueuse/core'
export const lazyPlugin = {
install(app) {
app.directive('img-lazy', {
mounted(el, binding) {
// el: 指令綁定的元素
// binding: binding.value 指令的綁定值 圖片url
console.log(el, binding.value);
useIntersectionObserver(
el, // 監(jiān)聽的元素
([{ isIntersecting }]) => {
// isIntersecting是一個(gè)布爾值 監(jiān)聽是否進(jìn)入可視區(qū)
console.log(isIntersecting);
if (isIntersecting) {
// 圖片進(jìn)入可視區(qū) 設(shè)置圖片的src
el.src = binding.value
}
}
)
}
})
}
}
main.js
// 引入懶加載指令并且注冊(cè)
import { lazyPlugin } from '@/directives'
app.use(lazyPlugin)問(wèn)題2:重復(fù)監(jiān)聽問(wèn)題uselntersectionObserver對(duì)于元素的監(jiān)聽是一直存在的,除非手動(dòng)停止監(jiān)聽,存在內(nèi)存浪費(fèi)
解決思路:在監(jiān)聽的圖片第一次完成加載之后就停止監(jiān)聽
代碼實(shí)現(xiàn):
// 定義懶加載指令
import { useIntersectionObserver } from '@vueuse/core'
export const lazyPlugin = {
install(app) {
app.directive('img-lazy', {
mounted(el, binding) {
// el: 指令綁定的元素
// binding: binding.value 指令的綁定值 圖片url
console.log(el, binding.value);
const {stop} = useIntersectionObserver(
el, // 監(jiān)聽的元素
([{ isIntersecting }]) => {
// isIntersecting是一個(gè)布爾值 監(jiān)聽是否進(jìn)入可視區(qū)
console.log(isIntersecting);
if (isIntersecting) {
// 圖片進(jìn)入可視區(qū) 設(shè)置圖片的src
el.src = binding.value
stop()
}
}
)
}
})
}
}總結(jié)
到此這篇關(guān)于前端vue3實(shí)現(xiàn)圖片懶加載的文章就介紹到這了,更多相關(guān)前端vue3圖片懶加載內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue watch響應(yīng)數(shù)據(jù)實(shí)現(xiàn)方法解析
這篇文章主要介紹了Vue watch響應(yīng)數(shù)據(jù)實(shí)現(xiàn)方法解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07
Vue-cli集成axios請(qǐng)求出現(xiàn)CORS跨域問(wèn)題及解決
這篇文章主要介紹了Vue-cli集成axios請(qǐng)求出現(xiàn)CORS跨域問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,2023-10-10
vue3給動(dòng)態(tài)渲染的組件添加ref的解決方案
ref和reactive一樣,也是用來(lái)實(shí)現(xiàn)響應(yīng)式數(shù)據(jù)的方法,下面這篇文章主要給大家介紹了關(guān)于vue3給動(dòng)態(tài)渲染的組件添加ref的解決方案,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-11-11
使用vue-cli(vue腳手架)快速搭建項(xiàng)目的方法
本篇文章主要介紹了使用vue-cli(vue腳手架)快速搭建項(xiàng)目的方法,vue-cli 是一個(gè)官方發(fā)布 vue.js 項(xiàng)目腳手架,使用 vue-cli 可以快速創(chuàng)建 vue 項(xiàng)目,感興趣的小伙伴們可以參考一下2018-05-05
基于Vue i18n插件實(shí)現(xiàn)Web應(yīng)用多語(yǔ)言切換功能
Vue i18n 是 Vue.js 官方的國(guó)際化插件,它允許開發(fā)者輕松地將多語(yǔ)言支持集成到Vue應(yīng)用中,下面我們將詳細(xì)介紹如何在Vue項(xiàng)目中引入并配置Vue i18n插件實(shí)現(xiàn)Web應(yīng)用多語(yǔ)言切換,需要的朋友可以參考下2025-07-07
使用Vue3實(shí)現(xiàn)簡(jiǎn)單的鼠標(biāo)跟隨效果
鼠標(biāo)跟隨效果是一種能顯著提升頁(yè)面交互性、增加動(dòng)態(tài)感與趣味性的常見方式,本文將使用Vue3實(shí)現(xiàn)簡(jiǎn)單的鼠標(biāo)跟隨效果,希望對(duì)大家有所幫助2025-09-09
Vue移動(dòng)端用淘寶彈性布局lib-flexible插件做適配的方法
這篇文章主要介紹了Vue移動(dòng)端用淘寶彈性布局lib-flexible插件做適配的操作方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-05-05
Vue源碼學(xué)習(xí)之關(guān)于對(duì)Array的數(shù)據(jù)偵聽實(shí)現(xiàn)
這篇文章主要介紹了Vue源碼學(xué)習(xí)之關(guān)于對(duì)Array的數(shù)據(jù)偵聽實(shí)現(xiàn),Vue使用了一個(gè)方式來(lái)實(shí)現(xiàn)Array類型的監(jiān)測(cè)就是攔截器,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-04-04
vue-cli3.0+element-ui上傳組件el-upload的使用
這篇文章主要介紹了vue-cli3.0+element-ui上傳組件el-upload的使用,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-12-12
關(guān)于vue中的時(shí)間格式轉(zhuǎn)化問(wèn)題
這篇文章主要介紹了關(guān)于vue中的時(shí)間格式轉(zhuǎn)化問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07

