图片懒加载(vue3)

2,939 阅读1分钟

前言:电商类网站的图片非常多,很有必要做一下图片懒加载,把网络性能优化做到 极致!

  • 实现步骤:
    • vue3全局指令的定义方式 app.directive,
    • 以插件的形式注册全局指令
    • 编写懒加载指令的具体逻辑
// vue2  
Vue.directive(指令名, {
	inserted (el, binding) {
	}
})
// vue3
app.directive(指令名, {
    // 指令所在的元素,dom结构被解析完成
    mounted (el, binding) {  
    }
})

1、新建src/directive/index.js,编写指令逻辑

// 导入默认图片
import defaultImg from '@/assets/images/01.png'
// 引入监听是否进入视口
import { useIntersectionObserver } from '@vueuse/core'
export default {
  // 需要拿到 main.js 中由 createApp 方法产出的 app 实例对象
  install (app) {
    // app 实例身上有我们想要的全局注册指令方法  调用即可
    app.directive('lazyImg', {
      mounted (el, binding) {
        // el:img dom对象
        // binding.value  图片url地址
        // 使用 vueuse/core 提供的监听 api 对图片 dom 进行监听 正式进入视口才加载
        // img.src = url
        console.log(el, binding)
        const { stop } = useIntersectionObserver(
          // 监听目标元素
          el,
          ([{ isIntersecting }], observerElement) => {
            if (isIntersecting) {
              // ◆图片加载失败显示默认图片
              el.onerror = function () {
                el.src = defaultImg
              }
              // ◆这里显示传过来的图片数据
              el.src = binding.value
              stop()// 中止监听
            }
          })
       }
    })
  }
}

2、main.js 里面导入自定义的全局图片懒加载指令,并注册插件

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

// ◆导入 图片懒加载指令
import imgPlugin from './directives'

// ◆链式编程:createApp.use(imgPlugin)
createApp(App).use(imgPlugin).use(store).use(router).mount('#app')

3、在需要的页面,使用 v-lazyImg 指令

<template>
  <HomePanel ref="target" title="人气推荐" sub-title="人气爆款 不容错过">
    <ul  class="goods-list">
      <li v-for="item in hotList" :key="item.id">
        <RouterLink to="/">
          <!-- <img :src="item.picture" alt=""> -->
          <!--◆ 使用自定义图片懒加载指令 -->
          <img v-lazyImg="item.picture" alt="">
          <p class="name">{{item.title}}</p>
          <p class="desc">{{item.alt}}</p>
        </RouterLink>
      </li>
    </ul>
  </HomePanel>
</template>

打开 network 下的 img 请求,慢慢滚动页面,会发现图片不是一次性加载出来的,这就实现了图片懒加载