手摸手教你利用defineAsyncComponent实现长页面按需加载组件

背景

产品设计了个首页,一次性加载30个左右的图表,wtf, 当然一次性加载也无可厚非,按照现在浏览器的性能,30个图表渲染还是没什么大问题的。

但是写都写了,试试看怎么实现按需加载。

技术需求:当页面向下滚动的时候,加载响应的组件,类似图片懒加载

demo效果

默认加载A,B组件, 划动动态加载相应的组件。

vue3中代码实现

defineAsyncComonent作用

官方文档

当我们这样引入组件, 是默认给注册好的,但是我们想让组件需要的时候再注册,这时候就要用到defineAsyncComonent

js 复制代码
import A form './A.vue'

改为异步加载组件函数

js 复制代码
const loadComponent = (name: string) =>
  defineAsyncComponent({
    loader: () => import(`./${name}.vue`),
  })

1、组件目录

2、完整代码实现

js 复制代码
<script setup lang="ts">
  // 异步加载组件函数
  const loadComponent = (name: string) =>
    defineAsyncComponent({
      loader: () => import(`./${name}.vue`),
    })

  // 所有组件的名称
  const componentNames = ['A', 'B', 'C', 'D']
  // 所有组件存的数组
  const components = componentNames.map((name) => {
    return {
      name,
      component: loadComponent(name),
    }
  })
  // 需要动态加载的组件名称
  const dynamicComponentName = ['C', 'D']
  // 默认加载的组件名称[], 划到底部后, 从组件名称里面拿出一个,添加到此数组里面
  const displayComponents = ref(['A', 'B'])

  /** ********************滚动***********************/
  // 开始观察滚动触发元素
  const contentRef = ref()

  const handleScroll = () => {
    const container = contentRef.value
    // 判断是否滚动到底部
    if (container.scrollTop + container.clientHeight >= container.scrollHeight) {
      console.log('滚到底部了, 开始加载')
      if (dynamicComponentName.length) {
        displayComponents.value.push(dynamicComponentName.shift()!)
      }
    }
  }
</script>
<template>
  <div ref="contentRef" class="load-component" @scroll="handleScroll">
    <template v-for="(i, index) in components" :key="index">
      <component :is="i.component" v-if="displayComponents.includes(i.name)" />
    </template>
  </div>
</template>

<style scoped lang="scss">
  .load-component {
    height: 100%;
    overflow-y: scroll;
    .fix-btn {
      position: fixed;
      top: 0;
    }
  }
</style>

实际项目效果

用到的以往技术

相关推荐
小雨青年21 分钟前
MateChat 进阶实战:打造零后端、隐私安全的“端侧记忆”智能体
前端·华为·ai·华为云·状态模式
勇气要爆发34 分钟前
问:ES5和ES6的区别
前端·ecmascript·es6
永不停歇的蜗牛1 小时前
Maven的POM文件相关标签作用
服务器·前端·maven
芳草萋萋鹦鹉洲哦1 小时前
【vue/js】文字超长悬停显示的几种方式
前端·javascript·vue.js
HIT_Weston2 小时前
47、【Ubuntu】【Gitlab】拉出内网 Web 服务:Nginx 事件驱动分析(一)
前端·ubuntu·gitlab
开发者小天2 小时前
React中的 闭包陷阱
前端·javascript·react.js
翔云 OCR API2 小时前
承兑汇票识别接口技术解析-开发者接口
开发语言·前端·数据库·人工智能·ocr
涔溪2 小时前
Vue3 的核心语法
前端·vue.js·typescript
G***E3163 小时前
前端在移动端中的React Native Web
前端·react native·react.js
云烟飘渺o3 小时前
JPA 的脏检查:一次“没 save() 却更新了”的排查记录
前端