Home  >  Article  >  Web Front-end  >  How to use vue3 image lazy loading IntersectionObserver and useIntersectionObserver

How to use vue3 image lazy loading IntersectionObserver and useIntersectionObserver

WBOY
WBOYforward
2023-05-15 23:31:041333browse

1. Create helloworld.js under src. The content is as follows

// 随便导入一张图片作为加载出错时的默认图片
import defaultImg from '@/assets/logo.svg'

import {useIntersectionObserver} from "@vueuse/core"; //图片加载失败时候用的图片
export default {
    install (app) {
        defineDirective(app)//自定义指令
    }
}

// 自定义指令
const defineDirective = (app) => {
    // 1.图片懒加载指令v-lazyLoad
// 原理:先存储图片地址不能在src上,当图片进入可视区,将你存储图片地址设置给图片元素(dom)的src即可。
    app.directive('lazyLoad', {
        // vue2.0监听使用指令的DOM是否创建好,钩子函数: inserted
        // vue3.0 的指令拥有的钩子函数和组件的一样,使用指令的DON是否创建好,钩子函数: mounted,onMounted是在组合API时候使用,现在是选项
        mounted (el, binding) { // 绑定的元素,绑定的值
            // // 2.创建一个观察对象,来观察当前使用指令得元素

            const observe = new IntersectionObserver(([{isIntersecting}]) => {
                if (isIntersecting) { // 如果进入了可视区
                    // 谁进入了可视区?得用observe去观察 是哪个元素使用了该指令,所以会传入dom对象el
                    // 停止观察,因为观察一次就够了
                    observe.unobserve(el)
                    // console.log(binding.value, el) // binding.value就是绑定的地址
                    // 3.监听图片加载失败,用默认图
                    el.onerror = () => {
                        el.src = defaultImg
                    }
                    // 4.将指令v-lazyLoad上的地址设置给el的src属性
                    el.src = binding.value
                }
            }, {
                threshold: 0//进入到可视区交界就开始观察
            })
            observe.observe(el)// 使用observe上的observe方法观察这个dom元素
        }
            // const { stop } = useIntersectionObserver(
            //     // 监听目标元素
            //     el,
            //     ([{ isIntersecting }], observerElement) => {
            //         if (isIntersecting) {
            //             // 当图片url无效加载失败的时候使用默认图片替代
            //             el.onerror = function () {
            //                 el.src = defaultImg
            //             }
            //             console.log('加载')
            //             el.src = binding.value
            //             stop()
            //         }
            //     })
            // }
    })
}

The mounted code below is a way. This way does not require the use of plug-ins and does not require the installation of anything.

const observe = new IntersectionObserver(([{isIntersecting}]) => {
        if (isIntersecting) { // 如果进入了可视区
            // 谁进入了可视区?得用observe去观察 是哪个元素使用了该指令,所以会传入dom对象el
            // 停止观察,因为观察一次就够了
            observe.unobserve(el)
            // console.log(binding.value, el) // binding.value就是绑定的地址
            // 3.监听图片加载失败,用默认图
            el.onerror = () => {
                el.src = defaultImg
            }
            // 4.将指令v-lazyLoad上的地址设置给el的src属性
            el.src = binding.value
        }
    }, {
        threshold: 0//进入到可视区交界就开始观察
    })
    observe.observe(el)// 使用observe上的observe方法观察这个dom元素
}

mounted The comment below is another method. This method requires the installation of plug-ins. Click to enter the tutorial during the installation process.

// const { stop } = useIntersectionObserver(
//     // 监听目标元素
//     el,
//     ([{ isIntersecting }], observerElement) => {
//         if (isIntersecting) {
//             // 当图片url无效加载失败的时候使用默认图片替代
//             el.onerror = function () {
//                 el.src = defaultImg
//             }
//             console.log('加载')
//             el.src = binding.value
//             stop()
//         }
//     })
// }

2. Import and use

import { createApp } from 'vue'
import App from './App.vue'
import './assets/reset.css'
import Vant from 'vant'
import 'vant/lib/index.css';
// 导入自己UI组件库
import UI from './helloworld'

// 插件的使用,在main.js使用app.use(插件)
createApp(App).use(Vant).use(UI).mount('#app')
// 具体就是导入这个
// import UI from './helloworld'
// 再use(UI)

3 in main.js. Then Use the following in app.vue:

<template>
  <div class="cs"></div>
  <ul >
    <li v-for="item in image_list" :key="item">
<!--      原本的写法-->
      <!-- <img :src="item.picture"  alt=""> -->
<!--      // 使用图片懒加载指令-->
      <img v-lazyLoad="item"  alt="">
    </li>
  </ul>
</template>
<script setup>
import {nextTick, onMounted, ref} from "vue";
const image_list = ref([
    &#39;https://yanxuan-item.nosdn.127.net/a6939f41c48fa9e9c8f7a7ed855351f1.jpg&#39;,
    &#39;https://yanxuan-item.nosdn.127.net/0cdfd546f8675669b87716114ad5900a.jpg&#39;,
    &#39;https://yanxuan-item.nosdn.127.net/240983ccc935146a4795e3990d30468d.jpg&#39;,
    &#39;https://yanxuan-item.nosdn.127.net/d46e005025a5d3b73c4781d31b327558.jpg&#39;,
    &#39;https://yanxuan-item.nosdn.127.net/330913911087b44b0d817dd78233165f.png&#39;,
    &#39;https://yanxuan-item.nosdn.127.net/9d9590bdb4f7cdd874de6a4554abcff9.jpg&#39;,
    &#39;https://yanxuan-item.nosdn.127.net/cd9060820a1a52f296fa2502e56a5872.jpg&#39;
])
</script>

<style lang="less" scoped>
.cs{
  height: 1000px;
  background-color: pink;
}
.outer{
  img{
    display: inline-block;
    width: 500px;
  }
}
.inner{
  display: inline-block;
  width: 500px;
  height: 50px;
  background-color: deeppink;
}
</style>

The above is the detailed content of How to use vue3 image lazy loading IntersectionObserver and useIntersectionObserver. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:yisu.com. If there is any infringement, please contact admin@php.cn delete