针对前端vue2项目中,优化需要加载多张图表的页面,并且每张图表需要从后端请求数据回显,可以通过以下方案实现:
- 封装图表组件LazyChart.vue
- 父组件按照顺序加载图表
- 封装图表组件使用IntersectionObserver API监听图表是否进入可视区域
- 进入可视区域调用接口等
代码实现
父页面
<template>
<div class="chart-page-box">
<div class="chart-box" v-for="item in chartData" :key="item.id">
<LazyChart :content="item.content"></LazyChart>
</div>
</div>
</template>
<script>
import LazyChart from "@/components/LazyChart.vue";
export default {
name: "ChartPage.vue",
components: {
LazyChart
},
data() {
return {
chartData: []
}
},
created() {
for (let i = 0; i < 30; i++) {
this.chartData.push({
id: i,
content: `chart图表${i+1}`
})
}
}
}
</script>
<style scoped lang="scss">
.chart-page-box {
display: flex;
flex-wrap: wrap;
.chart-box {
}
}
</style>
图表组件
<template>
<div class="lazy-chart-container" ref="container">
<div class="content">{{content}}</div>
</div>
</template>
<script>
export default {
name: "lazyChart",
props: {
content: {
type: String,
required: true,
default: () => ''
}
},
data () {
return {
observer: null
}
},
mounted() {
let options = {
root: null, // 默认为视窗
rootMargin: '0px', // 视窗的外边距
threshold: 0.1 // 目标元素可见比例达到 10% 时触发回调
};
const that = this
function callback(entries) {
entries.forEach(entry => {
if (entry.isIntersecting) {
console.log(`Element is visible in the viewport! ${that.content}`);
// todo 这里可进行接口调用等
}
});
}
this.observer = new IntersectionObserver(callback, options)
// observe 方法一定要写对
this.observer.observe(this.$refs.container)
},
methods: {
}
}
</script>
<style lang="scss" scoped>
.lazy-chart-container {
width: 500px;
height: 350px;
.content {
}
}
</style>