使用v-lazy实现VUE3图片懒加载技术

项目场景:

图片懒加载是常见的性能优化方法,在图片很多或加载图片出现网络延迟的情况下,使用懒加载可以减少网络请求、提高用户体验感。

实现原理:在图片没进入可视区域前,使用默认的图片;在进入可视区域并加载好之后,再替换图片的默认src路径,展示真实图片。

vue3已经封装好了v-lazy自定义指令,直接安装使用即可


使用方法:

1、vue3 安装 vue-lazy

npm install vue3-lazy -S

也可以用yarn安装

2、在main.js里面全局注册

import {
    
     createApp } from 'vue'
import App from './App.vue'
createApp(App).use(lazyPlugin, {
    
    
  loading: require('@/assets/images/default.png'), // 图片加载时默认图片
  error: require('@/assets/default.png') // 图片加载失败时默认图片
  // 还可以有其他配置
})

3、template中使用

<div id="app">
    <img v-lazy="../xxx.png">
</div>

原作者github地址(源码):https://github.com/ustbhuangyi/vue3-lazy

实现原理

Vue.js虽然是数据驱动+组件化,但还是避免不了手动操作DOM的情况,于是设计了自定义指令,允许用户做一些底层的DOM操作。v-lazy就是使用自定义指令实现的。

自定义指令官网https://cn.vuejs.org/guide/reusability/custom-directives.html#directive-hooks

为了自定义指令方便的给多个项目使用,可以把它做成插件:

const lazyPlugin = {
    
    
  install (app, options) {
    
    
    app.directive('lazy', {
    
    
      // 指令对象
    })
  }
}

export default lazyPlugin

然后在项目中使用:

import {
    
     createApp } from 'vue'
import App from './App.vue'
import lazyPlugin from 'vue3-lazy'

createApp(App).use(lazyPlugin, {
    
    
  // 添加一些配置参数
})

通常vue3的插件会暴露install函数,当app实例use该插件时,就会执行函数。在install函数内部,通过app.directive去注册一个全局指令,这样就可以在组件中使用了。

v-lazy的实现原理https://zhuanlan.zhihu.com/p/439390274

判断图片是否进入可视区域

判断图片是否进入可视区域使用的是 IntersectionObserver API ,详见MDN:https://developer.mozilla.org/zh-CN/docs/Web/API/IntersectionObserver,此时可以通过监听图片可滚动父元素的一些事件如 scroll、resize 等,然后通过一些 DOM 计算来判断图片元素是否进入可视区。
使用例子:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>IntersectionObserver</title>
</head>
<body>
    <div id="root" style="width: 700px; height: 1900px;">
        <div class="label topLeft" style="background-color: red; width: 200px; height: 200px;"></div>
    </div>
</body>
<script>
    debugger
    const intersectionObserver = new IntersectionObserver((entries) => {
    
    
        // 如果 intersectionRatio 为 0,则目标在视野外,
        // 我们不需要做任何事情。
        if (entries[0].intersectionRatio <= 0) return;
        console.log('Loaded new items');
    });
    // 开始监听
    intersectionObserver.observe(document.querySelector(".topLeft"));
</script>
</html>

猜你喜欢

转载自blog.csdn.net/weixin_42936434/article/details/130655232
今日推荐