Vue组件懒加载的操作代码

 更新时间:2023年09月21日 08:53:53   作者:chuckQu  
在本文中,我们学习了如何使用 Intersection Observer API 和 defineAsyncComponent 函数在 Vue 组件可见时对其进行懒加载,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友一起看看吧

在当今快节奏的数字世界中,网站性能对于吸引用户和取得成功至关重要。然而,对于像首页这样的页面,在不影响功能的前提下优化性能就成了一项挑战。

这就是 Vue 组件懒加载的用武之地。通过将非必要元素的加载推迟到可见时进行,开发人员可以增强用户体验,同时确保登陆页面的快速加载。

懒加载是一种优先加载关键内容,同时推迟加载次要元素的技术。这种方法不仅能缩短页面的初始加载时间,还能节约网络资源,从而使用户界面更轻量、反应更灵敏。

在本文中,我将向你展示一种简单的机制,使用 Intersection Observer API 在 Vue 组件可见时对其进行懒加载。

Intersection Observer API

Intersection Observer API 是一种功能强大的工具,它允许开发人员有效地跟踪和响应浏览器视口中元素可见性的变化。

它提供了一种异步观察元素与其父元素之间或元素与视口之间交集的方法。它为检测元素何时可见或隐藏提供了性能优越的优化解决方案,减少了对低效滚动事件监听器的需求,使开发人员能够在必要时有选择地加载或操作内容,从而增强用户体验。

它通常用于实现诸如无限滚动和图片懒加载等功能。

异步组件

Vue 3 提供了 defineAsyncComponent,用于仅在需要时异步加载组件。

它返回一个组件定义的 Promise:

import { defineAsyncComponent } from 'vue'
const AsyncComp = defineAsyncComponent(() => {
  return new Promise((resolve, reject) => {
    // ...load component from server
    resolve(/* loaded component */)
  })
})

还可以处理错误和加载状态:

const AsyncComp = defineAsyncComponent({
  // the loader function
  loader: () => import('./Foo.vue'),
  // A component to use while the async component is loading
  loadingComponent: LoadingComponent,
  // Delay before showing the loading component. Default: 200ms.
  delay: 200,
  // A component to use if the load fails
  errorComponent: ErrorComponent,
  // The error component will be displayed if a timeout is
  // provided and exceeded. Default: Infinity.
  timeout: 3000
})

当组件可见时,我们将使用该功能异步加载组件。

懒加载组件

现在,让我们结合 Intersection Observer API 和 defineAsyncComponent 函数,在组件可见时异步加载它们:

import {
  h,
  defineAsyncComponent,
  defineComponent,
  ref,
  onMounted,
  AsyncComponentLoader,
  Component,
} from 'vue';
type ComponentResolver = (component: Component) => void
export const lazyLoadComponentIfVisible = ({
  componentLoader,
  loadingComponent,
  errorComponent,
  delay,
  timeout
}: {
  componentLoader: AsyncComponentLoader;
  loadingComponent: Component;
  errorComponent?: Component;
  delay?: number;
  timeout?: number;
}) => {
  let resolveComponent: ComponentResolver;
  return defineAsyncComponent({
    // the loader function
    loader: () => {
      return new Promise((resolve) => {
        // We assign the resolve function to a variable
        // that we can call later inside the loadingComponent 
        // when the component becomes visible
        resolveComponent = resolve as ComponentResolver;
      });
    },
    // A component to use while the async component is loading
    loadingComponent: defineComponent({
      setup() {
        // We create a ref to the root element of 
        // the loading component
        const elRef = ref();
        async function loadComponent() {
            // `resolveComponent()` receives the
            // the result of the dynamic `import()`
            // that is returned from `componentLoader()`
            const component = await componentLoader()
            resolveComponent(component)
        }
        onMounted(async() => {
          // We immediately load the component if
          // IntersectionObserver is not supported
          if (!('IntersectionObserver' in window)) {
            await loadComponent();
            return;
          }
          const observer = new IntersectionObserver((entries) => {
            if (!entries[0].isIntersecting) {
              return;
            }
            // We cleanup the observer when the 
            // component is not visible anymore
            observer.unobserve(elRef.value);
            await loadComponent();
          });
          // We observe the root of the
          // mounted loading component to detect
          // when it becomes visible
          observer.observe(elRef.value);
        });
        return () => {
          return h('div', { ref: elRef }, loadingComponent);
        };
      },
    }),
    // Delay before showing the loading component. Default: 200ms.
    delay,
    // A component to use if the load fails
    errorComponent,
    // The error component will be displayed if a timeout is
    // provided and exceeded. Default: Infinity.
    timeout,
  });
};

让我们分解一下上面的代码:

我们创建一个 lazyLoadComponentIfVisible 函数,该函数接受以下参数:

  • componentLoader:返回一个解析为组件定义的 Promise 的函数
  • loadingComponent:异步组件加载时使用的组件。
  • errorComponent:加载失败时使用的组件。
  • delay:显示加载组件前的延迟。默认值:200 毫秒。
  • timeout:如果提供了超时时间,则将显示错误组件。默认值:Infinity

函数返回 defineAsyncComponent,其中包含在组件可见时异步加载组件的逻辑。

主要逻辑发生在 defineAsyncComponent 内部的 loadingComponent 中:

我们使用 defineComponent 创建一个新组件,该组件包含一个渲染函数,用于在传递给 lazyLoadComponentIfVisible 的 div中渲染 loadingComponent。该渲染函数包含一个指向加载组件根元素的模板ref

在 onMounted 中,我们会检查 IntersectionObserver 是否受支持。如果不支持,我们将立即加载组件。否则,我们将创建一个 IntersectionObserver,用于观察已加载组件的根元素,以检测它何时变得可见。当组件变为可见时,我们会清理观察者并加载组件。

现在,你可以使用该函数在组件可见时对其进行懒加载:

<script setup lang="ts">
import Loading from './components/Loading.vue';
import { lazyLoadComponentIfVisible } from './utils';
const LazyLoaded = lazyLoadComponentIfVisible({
  componentLoader: () => import('./components/HelloWorld.vue'),
  loadingComponent: Loading,
});
</script>
<template>
  <LazyLoaded />
</template>

总结

在本文中,我们学习了如何使用 Intersection Observer API 和 defineAsyncComponent 函数在 Vue 组件可见时对其进行懒加载。如果有一个包含许多组件的首页,并希望改善应用程序的初始加载时间,这将非常有用。

到此这篇关于Vue组件懒加载的文章就介绍到这了,更多相关Vue组件懒加载内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Vue element树形控件添加虚线详解

    Vue element树形控件添加虚线详解

    这篇文章主要为大家介绍了Vue element树形控件添加虚线,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助<BR>
    2021-11-11
  • Vue.js实现大转盘抽奖总结及实现思路

    Vue.js实现大转盘抽奖总结及实现思路

    这篇文章主要介绍了 Vue.js实现大转盘抽奖总结及实现思路,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-10-10
  • vue实现滑块拖拽校验功能的全过程

    vue实现滑块拖拽校验功能的全过程

    vue验证滑块功能,在生活中很多地方都可以见到,使用起来非常方便,这篇文章主要给大家介绍了关于vue实现滑块拖拽校验功能的相关资料,需要的朋友可以参考下
    2021-08-08
  • vue实现数字加逗号分隔

    vue实现数字加逗号分隔

    在Vue项目中,对数字进行格式化,实现带小数的数字三位一分隔的效果,可以通过自定义过滤器来实现,使用JavaScript的toLocaleString方法可以方便地将数字转换成带逗号的格式
    2024-10-10
  • vue实现固定位置显示功能

    vue实现固定位置显示功能

    这篇文章主要介绍了vue实现固定位置显示功能,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-05-05
  • Vue之mixin混入详解

    Vue之mixin混入详解

    这篇文章主要为大家介绍了Vue之mixin混入,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2021-11-11
  • Vue echarts模拟后端数据流程详解

    Vue echarts模拟后端数据流程详解

    在平常的项目中,echarts图表我们也是使用的非常多的,通常我们从后端拿到数据,需要在图表上动态的进行呈现,接下来我们就模拟从后端获取数据然后进行呈现的方法
    2022-09-09
  • VueJs组件prop验证简单介绍

    VueJs组件prop验证简单介绍

    今天看了vuejs的组件,看到了prop组件,主要作用是在传入数据的时候对传入的值做判断,今天小编通过一个小例子给大家分享VueJs组件prop验证简单理解,感兴趣的朋友一起看看吧
    2017-09-09
  • Vue预渲染:prerender-spa-plugin生成静态HTML与vue-meta-info更新meta

    Vue预渲染:prerender-spa-plugin生成静态HTML与vue-meta-info更新meta

    Vue.js中,prerender-spa-plugin和vue-meta-info插件的结合使用,提供了解决SEO问题的方案,prerender-spa-plugin通过预渲染技术生成静态HTML,而vue-meta-info则能动态管理页面元数据,本文将探讨如何使用这两个工具优化Vue.js项目的SEO表现,包括安装、配置及注意事项
    2024-10-10
  • 使用VUE+iView+.Net Core上传图片的方法示例

    使用VUE+iView+.Net Core上传图片的方法示例

    这篇文章主要介绍了使用VUE+iView+.Net Core上传图片的方法示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-01-01

最新评论