图片懒加载(Lazy Loading)是一种前端优化技术,旨在改善网页加载性能和用户体验。它的基本原理是,将网页中的图片延迟加载,只有当用户滚动到图片所在的位置时,才会加载图片内容,从而减少初始页面加载时的网络请求量,加快页面加载速度。
图片懒加载的优势包括:
-
减少初始加载时间: 只加载可视区域的图片,减少了初始页面加载所需的时间,提高了用户体验。
-
降低网络请求: 不需要一开始就加载所有图片,减少了不必要的网络请求,节省了带宽。
-
优化移动设备体验: 在移动设备上,网络速度可能较慢,图片懒加载可以显著提升页面加载速度。
-
节省资源: 不加载不可见区域的图片,减少了服务器和客户端的资源消耗。
Vue.js 可以通过使用第三方库或者自定义指令来实现图片的懒加载。
一.第三方库实现
首先,在你的 Vue 项目中安装 vue-lazyload
库
javascript
npm install vue-lazyload --save
在 main.js 中引入和使用
这里是全局的引入,也可以按需引入
javascript
import { createApp } from 'vue'
import App from './App.vue'
import VueLazyload from 'vue-lazyload';
const app = createApp(App)
app.use(VueLazyload)
app.mount('#app')
在组件中使用懒加载
在需要懒加载的图片元素上使用 v-lazy
指令,将图片的 src
属性替换成 v-lazy
javascript
<template>
<div>
<!-- 普通加载的图片 -->
<img src="normal-image.jpg" alt="Normal Image" />
<!-- 使用懒加载的图片 -->
<img v-lazy="lazy-image.jpg" alt="Lazy Loaded Image" />
</div>
</template>
<script>
</script>
二.自定义指令实现
首先安装VueUse
javascript
npm i @vueuse/core
VueUse介绍
vueuse
是一个为 Vue.js 提供常用功能和自定义组合的库,旨在帮助开发者更轻松地构建 Vue 应用。它提供了一系列的 Composition API 组合函数,用于处理诸如状态管理、副作用、浏览器 API 等常见任务,以及一些自定义的功能。
以下是一些 vueuse
库提供的功能和特性:
-
常用 Composition API 函数:
vueuse
提供了许多与 Composition API 相关的实用函数,如useLocalStorage
(用于在本地存储中保留状态)、useDebounce
(用于防抖处理)、useIntersectionObserver
(用于观察元素是否进入视口)、useEventListener
(用于添加事件监听器)等等。 -
浏览器 API 包装:
vueuse
还对浏览器原生 API 进行了封装,使它们更易于在 Vue 应用中使用,如useMouse
(获取鼠标位置)、useGeolocation
(获取地理位置信息)、useIdle
(检测用户是否处于空闲状态)等。 -
状态管理: 除了提供一些状态管理相关的功能外,
vueuse
还包括了useStore
,这是一个基于 Composition API 的状态管理工具,可以在应用中更轻松地管理全局状态。 -
自定义组合:
vueuse
鼓励开发者创建自己的自定义组合,这可以帮助你把常见的逻辑封装成可重用的组合函数,从而简化代码和提高代码的可维护性。
使用该库的 useIntersectionObserver函数,监听图片是否出现在可视区域
封装指令---directives/index.js
javascript
import { useIntersectionObserver } from '@vueuse/core'
export const lazyPlugin = {
install (app) {
// 懒加载指令逻辑
app.directive('img-lazy', {
mounted (el, binding) {
// el: 指令绑定的那个元素 img
// binding: binding.value 指令等于号后面绑定的表达式的值 图片url
console.log(el, binding.value)
const { stop } = useIntersectionObserver(
el,
([{ isIntersecting }]) => {
console.log(isIntersecting)
if (isIntersecting) {
// 进入视口区域
el.src = binding.value
stop() //当图片已经渲染出来后,停止监听
}
},
)
}
})
}
}
-
导入
useIntersectionObserver
: 这行代码导入了@vueuse/core
库中的useIntersectionObserver
函数,它是用来实现 Intersection Observer 的功能,可以用于观察元素是否进入视口。 -
定义
lazyPlugin
插件对象: 这个对象有一个install
方法,用于在 Vue 应用中安装插件。 -
app.directive('img-lazy', {...})
: 这里使用app.directive
方法来注册一个自定义指令img-lazy
。该指令将在具有v-img-lazy
属性的图片元素上生效。 -
mounted
钩子函数: 当绑定了img-lazy
指令的图片元素被插入到 DOM 中时,mounted
钩子函数会被调用。在这个函数内部,你使用了useIntersectionObserver
来监测图片元素是否进入视口。 -
useIntersectionObserver
: 这个函数的参数包括要观察的元素el
,以及当元素状态变化时的回调函数。回调函数接收一个参数,包含当前的观察结果。在这里,你解构出isIntersecting
变量,表示元素是否进入视口。 -
if (isIntersecting) {...}
: 如果元素进入了视口,就会执行这个条件语句。在这里,你将图片元素的src
属性设置为binding.value
,即绑定到指令的表达式的值,这通常是图片的 URL。然后调用stop()
方法停止对元素的可见性变化进行观察。
全局注册
javascript
// 全局指令注册
import {lazyPlugin } from '@/directives/index'
app.use(lazyPlugin)
指令使用
javascript
<img v-img-lazy="cate.picture"/>//cate.picture图片的url