vue3图片懒加载指令(typescript)


前言

图片懒加载能减少服务器压力,比如一个前台展示网站,里面包含很多图片,如某宝它有很多商品的图片,但是用户不一定会浏览完整的网页,用户可能从某个分类的入口进入到了别的页面,那么就会造成加载了这么多的图片,压根没人看的境地;


介绍场景

一个页面里面用v-for遍历了一个带有12张图片的数组,一共12个标签

  <div class="img-lazy p-6">
    <img :src="item" v-for="item in images" :key="item" />
  </div>

未使用懒加载时

页面一出来,滚动条在最顶部的时候,浏览器的网络进程会把img所需要的图片获取下来,然后交给渲染主线程去解析html,于是同一时间请求页面所有的图片;

在这里插入图片描述

使用懒加载后

使用图片懒加载后,只会加载在视口内的图片和缺省图片,当其它图片滚动到视口的时候才请求图片,如下图所示;

在这里插入图片描述

当然您还得考虑用户网络的状况,如果用户网络不佳,图片还没有请求到的时候可以使用缺省图代替;如下图所示

在这里插入图片描述

写vue3指令

此处用的是vueUse库来实现,详细的你可以查看vueUse

当然如果你不想用vueUse库,那么你也可以使用原生接口IntersectionObserver

import { useIntersectionObserver } from '@vueuse/core';
export default {
  mounted(el: HTMLImageElement) {
    //如果不是图片的话就不触发懒加载
    if (!(el instanceof HTMLImageElement)) return;
    // 把真正的地址暂存起来
    const _src = el.src;
    //设置个缺省图片
    el.setAttribute('src', '/loading.png');
    //如果你不想用vueuse,你也可以用原生的IntersectionObserver接口来实现
    const { stop } = useIntersectionObserver(el, ([{ isIntersecting }]) => {
      if (isIntersecting) {
        //说明到视口中了,那就把真实的地址还原回去
        el.setAttribute('src', _src);
        //同时关闭Observer观察
        stop();
      }
    });
  },
};


全局注册指令

我是以插件的形式注册全局指令的,避免main.ts太多代码,看个人习惯你也可以其他写法,代码如下(示例):

import { App } from 'vue';//App是接口,做ts提示用
import lazyLoad from '/@/directives/lazyLoad';
export default {
  install(Vue: App<Element>) {
    Vue.directive('lazyLoad', lazyLoad);
  },
};


在页面使用指令v-lazyLoad

<template>
  <div class="img-lazy p-6">
    <img :src="item" v-for="item in images" :key="item" v-lazyLoad />
  </div>
</template>

<script setup name="imgLazy" lang="ts">
  const images = reactive<string[]>([
    'https://img-blog.csdnimg.cn/img_convert/29576b39b36e5c8681ee5f58409c0939.png',
    'https://img-blog.csdnimg.cn/img_convert/ac3416110cce6fd635d27c248a0b4fcc.png',
    'https://img-blog.csdnimg.cn/img_convert/b66edfe5bd07f16c3245a8270a97de06.png',
    'https://img-blog.csdnimg.cn/img_convert/586dc56f36de6e74c6a8fd816043b828.png',
    'https://img-blog.csdnimg.cn/img_convert/e0caff5972b2b620b0a1aacde5c33888.png',
    'https://img-blog.csdnimg.cn/img_convert/6048591a7cf2c455aaf4ddc800029266.png',
    'https://img-blog.csdnimg.cn/img_convert/64ba0169000f4650bb984fcc3622ba86.png',
    'https://img-blog.csdnimg.cn/img_convert/639e2439552cab7c4b58d3d2e21c170d.png',
    'https://img-blog.csdnimg.cn/img_convert/76351788d26e57a90e758004a9be4da2.png',
    'https://img-blog.csdnimg.cn/img_convert/41dfef919cca8fc8666b5e0f4a86a08d.png',
    'https://img-blog.csdnimg.cn/img_convert/96f3d6652819d02538ba9e5603df1815.png',
    'https://img-blog.csdnimg.cn/img_convert/e2a5e7840655b3b51cb498712f9b924d.png',
  ]);
</script>

<style lang="less" scoped>
  .img-lazy {
    img {
      @apply w-160 h-100 block mx-auto mb-6 rounded;
      &:not([src]) {
        opacity: 0;
      }
    }
  }
</style>

源码地址

github欢迎指正

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值