数据处理
- 分页:
- 使用
reactive
定义当前页码和每页显示数量。例如:
import { reactive } from 'vue';
const state = reactive({
currentPage: 1,
pageSize: 10,
total: 0,
dataList: []
});
- 根据当前页码和每页数量从原始大数据集中截取需要展示的数据。可以使用`computed`计算属性:
import { reactive, computed } from 'vue';
const state = reactive({
currentPage: 1,
pageSize: 10,
total: 0,
allData: []
});
const displayedData = computed(() => {
const start = (state.currentPage - 1) * state.pageSize;
const end = start + state.pageSize;
return state.allData.slice(start, end);
});
- 虚拟列表:
- 借助
@vueuse/core
库中的useVirtualList
等工具实现虚拟列表。在数据处理时,只渲染可见区域的数据。例如:
import { useVirtualList } from '@vueuse/core';
import { reactive } from 'vue';
const state = reactive({
largeData: Array.from({ length: 10000 }, (_, i) => i + 1)
});
const { items, scrollTo } = useVirtualList(state.largeData, {
height: 200,
itemHeight: 30
});
指令使用
- v - for 优化:
- 给
v - for
绑定的列表项提供唯一的key
值。这有助于Vue更高效地更新DOM。例如:
<template>
<div v - for="(item, index) in displayedData" :key="item.id">
{{ item.name }}
</div>
</template>
- 避免不必要的指令:
- 减少在列表项模板中使用会频繁触发重新渲染的指令,如
v - if
。如果需要根据条件显示或隐藏列表项,可以在数据处理阶段过滤数据,而不是在模板中使用v - if
。
组件设计
- 列表项组件化:
- 将列表项封装成单独的组件,提高代码复用性和可维护性。同时可以对列表项组件进行
keep - alive
缓存,减少重复渲染。例如:
<template>
<div>
<ListItem v - for="(item, index) in displayedData" :key="item.id" :data="item" />
</div>
</template>
<script setup>
import ListItem from './ListItem.vue';
</script>
- 懒加载:
- 对于图片等资源,可以在列表项组件中实现懒加载。可以使用
IntersectionObserver
结合reactive
数据来控制图片的加载时机。例如,在列表项组件中:
import { reactive, onMounted } from 'vue';
export default {
setup() {
const state = reactive({
isLoaded: false
});
onMounted(() => {
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
state.isLoaded = true;
observer.unobserve(entry.target);
}
});
});
const imgEl = document.getElementById('list - item - img');
if (imgEl) {
observer.observe(imgEl);
}
});
return {
state
};
}
};
<template>
<div>
<img v - if="state.isLoaded" :src="item.imgUrl" />
<img v - else src="placeholder.jpg" />
</div>
</template>