当前位置:首页 > VUE

自己实现vue懒加载

2026-02-21 04:51:13VUE

实现 Vue 懒加载的基本思路

懒加载(Lazy Loading)的核心思想是按需加载资源,通常在 Vue 中用于延迟加载组件或图片。以下是两种常见的实现方式:

组件懒加载

Vue 结合 Webpack 的动态导入(Dynamic Import)实现组件懒加载:

// 静态导入(非懒加载)
import StaticComponent from './StaticComponent.vue'

// 动态导入(懒加载)
const LazyComponent = () => import('./LazyComponent.vue')

export default {
  components: {
    StaticComponent,
    LazyComponent
  }
}

动态导入会返回一个 Promise,Webpack 会自动将动态导入的组件拆分为单独的 chunk,仅在需要时加载。

图片懒加载

实现图片懒加载需要监听元素是否进入视口:

自己实现vue懒加载

// 自定义指令实现
Vue.directive('lazy', {
  inserted: (el, binding) => {
    const observer = new IntersectionObserver((entries) => {
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          el.src = binding.value
          observer.unobserve(el)
        }
      })
    })
    observer.observe(el)
  }
})

// 使用方式
<img v-lazy="'path/to/image.jpg'" alt="Lazy Image">

优化懒加载体验

添加加载状态和错误处理:

Vue.directive('lazy', {
  inserted: (el, binding) => {
    el.src = 'placeholder.jpg' // 占位图
    const observer = new IntersectionObserver((entries) => {
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          const img = new Image()
          img.src = binding.value
          img.onload = () => {
            el.src = binding.value
          }
          img.onerror = () => {
            el.src = 'error.jpg' // 错误处理
          }
          observer.unobserve(el)
        }
      })
    })
    observer.observe(el)
  }
})

浏览器兼容性处理

对于不支持 IntersectionObserver 的浏览器:

自己实现vue懒加载

const lazyLoad = (el) => {
  const rect = el.getBoundingClientRect()
  return (
    rect.top <= (window.innerHeight || document.documentElement.clientHeight) &&
    rect.left <= (window.innerWidth || document.documentElement.clientWidth)
  )
}

Vue.directive('lazy', {
  inserted: function(el, binding) {
    function load() {
      if (lazyLoad(el)) {
        el.src = binding.value
        window.removeEventListener('scroll', load)
      }
    }
    window.addEventListener('scroll', load)
    load()
  }
})

性能优化建议

  1. 设置合适的 rootMargin 扩大触发范围:

    new IntersectionObserver(callback, {
    rootMargin: '200px'
    })
  2. 对大量图片使用节流:

    let ticking = false
    window.addEventListener('scroll', () => {
    if (!ticking) {
     window.requestAnimationFrame(() => {
       loadImages()
       ticking = false
     })
     ticking = true
    }
    })
  3. 预加载即将进入视口的资源:

    const observer = new IntersectionObserver((entries) => {
    entries.forEach(entry => {
     if (entry.isIntersecting || entry.boundingClientRect.top < 300) {
       // 加载逻辑
     }
    })
    }, {
    rootMargin: '300px'
    })

以上实现方式可以根据项目需求进行组合和调整,核心思想都是延迟资源的加载时机直到真正需要时。

标签: 加载vue
分享给朋友:

相关文章

vue实现多级组件

vue实现多级组件

实现多级组件的基本结构 在Vue中实现多级组件通常涉及父子组件嵌套,通过props向下传递数据,通过$emit向上传递事件。多级组件的核心是递归或动态组件渲染。 <!-- 父组件 Parent…

vue实现用户信息表

vue实现用户信息表

Vue 实现用户信息表的方法 使用 Vue CLI 创建项目 安装 Vue CLI 并初始化项目: npm install -g @vue/cli vue create user-info-tabl…

vue实现海报

vue实现海报

Vue 实现海报生成方案 使用 html2canvas 库 html2canvas 是一个将 HTML 元素转换为 Canvas 的库,适合将 Vue 组件渲染为海报图片 安装依赖: npm…

vue实现前端

vue实现前端

Vue 实现前端的核心方法与步骤 安装 Vue 项目 使用 Vue CLI 或 Vite 创建项目。Vue CLI 是传统构建工具,Vite 是新一代轻量级工具。 npm init vue@l…

vue实现selectable

vue实现selectable

Vue 实现可选择的 Select 组件 在 Vue 中实现一个可选择的 Select 组件,可以通过以下几种方式: 使用原生 HTML select 元素 <template>…

vue 实现图钉

vue 实现图钉

实现图钉效果的步骤 在Vue中实现图钉(固定位置)效果,可以通过CSS的position: sticky属性或监听滚动事件动态修改元素样式。以下是两种常见方法: 方法一:使用CSS的positio…