问题:页面过长,下面的图片不一定访问到,存在一定浪费。
解决方案:图片懒加载,仅当进入视口区,才发送请求显示图片。
- // 全局指令
- app.directive('指令名称',{
- mounted(el, binding){
- // el:指令绑定的元素
- // binding:绑定的表达式。binding.value为表达式的值
- }
- })
在入口文件main.js中,定义一个全局指令,第一个参数是指令名称,为 img-lazy,需要图片懒加载时,调用 v-img-lazy 实现。即 全局指令使用 v-指令名称 实现;第二个参数是一个钩子,钩子内的第一个参数是元素,第一个参数是绑定的表达式
vueuse插件中提供 useIntersectionObserver 方法,用于判断元素是否进去视口区。
- import { useIntersectionObserver } from '@vueuse/core'
- const { stop } = useIntersectionObserver(
- el,
- ([{ isIntersecting }]) => {
- ...
- // el:监听的目标对象/元素
- //isIntersecting: 是否进入视口区域
- }
- )
- import { useIntersectionObserver } from '@vueuse/core'
- const { stop } = useIntersectionObserver(
- el, // 监听的目标对象/元素
- ([{ isIntersecting }]) => {
- // 进入视口区域
- if(isIntersecting){
- el.src = binding.value
- stop() // 停止监听
- }
- }
- )
停止监听:由方法解构出 stop 方法,可用于在 第一次完成加载后,调用stop() 来停止监听。
模板中,使用 v-指令名 调用,如 v-img-lazy
-
'i.picture' /> - // <元素 v-指令名称='binding'>
问题:逻辑书写位置不合理(在main.js中写逻辑)
解决:将懒加载指令封装成插件,main.js入口文件仅负责注册插件。
- // src/directives/index.js中(插件中)
- const directivePlugin = {
- install(app){
- ... // 使用app实现懒加载指令
- }
- }
- // main.js
- import directivePlugin from '@/directives/index'
- app.use(directivePlugin) // 注册插件
完整代码:
(优化前)

优化后:

- // src/directives/index.js
- import { useIntersectionObserver } from '@vueuse/core'
- // 定义懒加载插件
- export const lazyPlugin = {
- install(app){
- // ★定义全局指令 - (懒加载实现思路:监听到进入视口,将src绑定给后面的值)
- // app挂载后,app.directive('指令名称', 钩子(el,binding){ })
- app.directive('img-lazy', {
- mounted(el, binding){
- // el: 指令绑定的那个元素 img
- // binding: binding.value 指令等于后面绑定的表达式的值 图片的url
-
- // vueuse插件的方法,useIntersectionObserver:是否进去视口区域,stop第一次加载后停止监听->重复加载
- const { stop } = useIntersectionObserver(
- el,
- ([{ isIntersecting }]) => {
- // console.log(isIntersecting);
- if(isIntersecting){
- el.src = binding.value
- stop()
- }
- }
- )
- }
- })
- }
- }