vue3-实现图片懒加载-@vueuse/core加上全局挂载指令v-imgLazy

345 阅读1分钟
  1. 首先需要安装依赖

    npm i @vueuse/core

    参考官网:vueuse.org/guide/#inst…

  2. 需要用到@vueuse/core的 API useIntersectionObserver

    const { stop } = useIntersectionObserver( 
        // target表示通过ref获取到的组件对象或Dom对象
        target, 
        // isIntersecting 代表组件对象是否进入可视区域
        ([{ isIntersecting }], observerElement) =>{
            if(isIntersecting) {
                // 进入可视区域,发请求,展示图片
            }
        }, 
    )
    
  3. 实现步骤

  • 实现一个空的插件
export const directivePlugin = {
  install (app) {
  }
}
  • 实现一个空的指令
app.directive('imgLazy', {
    mounted(el,binding){
    }
})
  • 实现懒加载的逻辑,注册插件
import { useIntersectionObserver } from '@vueuse/core'
export const directivePlugin = {
  install (app) {
    // console.log('app实参', app)
    app.directive('imgLazy', {
      // inserted:被绑定元素插入父节点时调用,vue2用的是inserted,vue3用的mounted
      // 第一个参数是dom,第二个参数是binding的dom
      mounted (el, binding) {
        const { stop } = useIntersectionObserver(
          el,
          // isIntersecting 代表组件对象是否进入可视区域
          ([{ isIntersecting }], observerElement) => {
            if (isIntersecting) {
              // 如果图片滚动到视口,就修改src属性,发请求,实现懒加载
              el.src = binding.value
              // stop 是停止监听的方法
              // 优化:如果图片加载出来了,就不再进行懒加载
              stop()
            }
          }
        )
      }
    })
  }
}
  • 注册到 全局 main.js
// 空插件注册
import { directivePlugin } from '@/directives'
createApp(App).use(store).use(router).use(directivePlugin).mount('#app')
  • 在img标签上使用自定义指令
<ul class="goods-list">
  <li v-for="item in newList" :key="item.id">
    <RouterLink :to="`/good/${item.id}`">
      <img v-imgLazy="item.picture" alt="" />
      <p class="name">{{ item.name }}</p>
      <p class="price">&yen;{{ item.price }}</p>
    </RouterLink>
  </li>
</ul>