自定义图片懒加载指令的实现

170 阅读2分钟

自定义图片懒加载指令的实现

思路

判断图片是否进入到视口区域

如何得知是否进入视口

  • 判断距离
  • 监听DOM : VueUse

只有进入视口区域才发送网络请求

如何发送默认的网络请求

img.src = url

为图片的 src 属性赋值,浏览器就会自动发送网络请求

实现步骤

  1. 先创建指令,让指令运行起来
  2. 在指令的内部实现懒加载的逻辑

实现过程

1、创建自定义指令

// 导入 createApp 方法
import { createApp } from 'vue'
// 导入 App 根组件
import App from './App.vue'// 调用 createApp 方法 创建 app 实例
const app = createApp(App)
​
// 注册自定义指令
app.directive('img-lazy', {
    /**
     * 自定义图片懒加载指令的mounted生命周期
     * @description 指令挂载之后自动执行
     * @param {HTMLImageElement} el 指令挂载的DOM实例
     * @param {Object} binding 该对象的value属性为,指令使用的值,可以通过其获得要进行懒加载处理的图片的url
     */
    mounted(el, binding) {
        console.log(el, binding.value) // 打印结果为img实例对象,传入的url值
        // 图片懒加载的核心逻辑
        // ......
    }
})
​
// 挂载 app 实例
app.mount('#app')

2、自定义指令的绑定

<script setup>
// 测试图片的地址
const url = 'https://gw.alipayobjects.com/zos/bmw-prod/0f93c777-5320-446b-9bb7-4d4b499f346d.svg'
</script><template>
  <!-- 增加占位盒子,将目标图片撑出视口范围 -->
  <div class="container">图片懒加载指令的测试</div>
  <!-- 绑定指令,传入的值为图片的地址 -->
  <img v-img-lazy="url">
</template><style lang="scss" scoped>
.container {
  height: 1000px;
  background-color: wheat;
}
</style>

3、核心逻辑实现

通过 VueUse 工具库中的 hook -- useIntersectionObserver 实现

安装VueUse工具库

npm i @vueuse/core

3.1 如何知道图片进入视口区域

    mounted(el, binding) {
        // 图片懒加载的核心逻辑
        // 1、如何知道图片进入视口区域 通过 VueUse 工具库中的 hook -- useIntersectionObserver 实现
        /**
         * 通过 useIntersectionObserver 实现对目标对象 el 是否在视口区域的监听
         * @description intersectionObserver 为浏览器提供的API,用于监听目标对象是否进入视口区域
         * @param {HTMLImageElement} el 目标对象
         * @param {boolean} isIntersecting 是否在视口区域
         */
        const { stop } = useIntersectionObserver(
            el,
            ([{ isIntersecting }], observerElement) => {
                // 如果目标对象在视口区域
                console.log(isIntersecting) // 当目标对象进入视口,打印true
            },
        )
    }

3.2 为进入视口区域的图片添加src属性

    mounted(el, binding) {
        // 图片懒加载的核心逻辑
        // 1、如何知道图片进入视口区域 通过 VueUse 工具库中的 hook -- useIntersectionObserver 实现
        /**
         * 通过 useIntersectionObserver 实现对目标对象 el 是否在视口区域的监听
         * @description intersectionObserver 为浏览器提供的API,用于监听目标对象是否进入视口区域
         * @param {HTMLImageElement} el 目标对象
         * @param {boolean} isIntersecting 是否在视口区域
         */
        const { stop } = useIntersectionObserver(
            el,
            ([{ isIntersecting }], observerElement) => {
                // 如果目标对象在视口区域
                if (isIntersecting) {
                    // 为目标的src属性赋值为图片的url
                    el.src = binding.value
                    // 停止监听 实现性能优化
                    stop()
                }
            },
        )
    }

学自 B站 柴柴_前端教书匠