背景
产品设计了个首页,一次性加载30个左右的图表,wtf, 当然一次性加载也无可厚非,按照现在浏览器的性能,30个图表渲染还是没什么大问题的。
但是写都写了,试试看怎么实现按需加载。
技术需求:当页面向下滚动的时候,加载响应的组件,类似图片懒加载
demo效果
默认加载A,B组件, 划动动态加载相应的组件。
vue3中代码实现
defineAsyncComponent
作用
当我们这样引入组件, 是默认给注册好的,但是我们想让组件需要的时候再注册,这时候就要用到defineAsyncComponent
import A form './A.vue'
改为异步加载组件函数
const loadComponent = (name: string) =>
defineAsyncComponent({
loader: () => import(`./${name}.vue`),
})
1、组件目录
2、完整代码实现
<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>