vue3借用数据懒加载实现图片懒加载

490 阅读1分钟

1. 自定义指令

在main.js中定义自定义指令

// 省略其他
const app = createApp(App)
app.directive('imgLazy', {
      mounted (el, binding) {
          console.log(el,binding,'imgLazy')
     }
  })

2. 使用自定义指令

<img v-imgLazy="src" ></img>

3. 输出自定义指令钩子函数的两个参数

image.png

可以看到:

el是指令绑定到的dom元素

binding.value是:<dom v-imgLazy=" binding.value的值"/>

4. 将代码封装到directives/index.js

const myDirective = {
  install (app) {
    // 自定义指令
    app.directive('imgLazy', {
      mounted (el, binding) {
        console.log(el,binding,'imgLazy')
      }
    })
  }
}

export default myDirective

main.js中引入,并使用

// 省略其他
// 引入全局指令
import myDirective from '@/directives'

const app = createApp(App)

app.use(store).use(router).use(myPlugin).use(myDirective).mount('#app')

5. 完善封装的函数

这里依旧用到数据懒加载插件 @vueuse/core

插件的简单用法,请看vue3复用数据懒加载

借用数据懒加载,在当前视图显示时再去请求图片,当请求还未回来之前显示默认图片

import { useIntersectionObserver } from '@vueuse/core'
// 默认图片
import defaultImage from '@/assets/images/200.png'

const myDirective = {
  install (app) {
    // 自定义指令
    app.directive('imgLazy', {
      mounted (el, binding) {
        el.src = defaultImage
        // el是指令绑定到的dom元素
        // binding.value是:<dom v-imgLazy=" binding.value的值"/>
        console.log(el, binding, 'imgLazy')
        const { stop } = useIntersectionObserver(el,
          ([{ isIntersecting }], abserveDom) => {
            if (isIntersecting) {
              stop()
              // 给dom元素设置src属性值
              el.src = binding.value
              el.onerror = () => {
                el.src = defaultImage
              }
            }
          },
          { threshold: 0 }
        )
      }
    })
  }
}

export default myDirective

6. 实现的效果图

网络较慢的时候:

小兔仙图片懒加载效果图2.gif

网络正常时: 小兔仙图片懒加载效果图.gif