vue自定义图片懒加载指令

直接上代码

/**
 * @Author : xlsir
 * @Description: 图片懒加载指令
 * @Create_time: 2025-08-03 10:34
 */
const ob = new IntersectionObserver(entries => {
    for (const entry of entries) {
        if (entry.isIntersecting) {
            const img = entry.target;
            // 图片预加载
            preloadImage(img)
            ob.unobserve(img);
        }
    }
}, {
    rootMargin: '200px',
    threshold: 0.01
});

//预加载
const preloadImage = (imgElement) => {
    const src = imgElement.dataset.src;
    if (!src) return;
    // 创建预加载的Image对象
    const preloadImg = new Image();
    preloadImg.src = src;
    // 预加载完成后再赋值给实际img元素
    preloadImg.onload = () => {
        imgElement.src = src;
        imgElement.removeAttribute('data-src');
    };
    // 加载失败时设置错误处理
    preloadImg.onerror = () => {
        imgElement.src = ''; // 或设置默认错误图片
        imgElement.removeAttribute('data-src');
    };
}

// 判断元素有没有在视口
function isBelowViewport(el) {
    const rect = el.getBoundingClientRect()
    return rect.top - window.innerWidth > 0
}

export default {
    mounted(el) {
        //当元素处于视口  直接记载 而不是 观测
        if (!isBelowViewport(el)) {
            preloadImage(el);
            return
        }
        ob.observe(el);
    },
    unmounted(el) {
        ob.unobserve(el);
    }
};

如何使用

  1. main.js注册

    import { createApp } from 'vue'
    import App from './App.vue'
    import vLazyImg from '@/directives/vLazyImg.js' //引入指令文件
    const app = createApp(App)
    
    app.directive('img-lazy',vLazyImg)
    app.mount('#app')
  2. 文件使用

      <img v-lazy-img>
评论区
头像