功能目标:
CardList.vue
中支持分页,每页显示指定数量的卡片。- 添加“加载中”动画。
- 支持懒加载:滚动到底部自动加载下一页。
- 点击卡片的事件逻辑由
Card.vue
内部发出,并由CardList
向上传递。
主页面文件 Home.vue
<template><div><h1>Card List 示例</h1><CardList :dataList="cards" @card-click="handleCardClick" /></div>
</template><script>
import CardList from './components/CardList.vue'export default {name: 'Home',components: {CardList},data() {return {// 假设这是全部数据(实际应用中可从API分页加载)cards: Array.from({ length: 50 }, (_, i) => ({id: i + 1,title: `Card #${i + 1}`,description: `This is card number ${i + 1}.`}))}},methods: {handleCardClick(card) {alert(`你点击了: ${card.title}`)}}
}
</script>
CardList.vue
(分页 + 懒加载 + 加载动画)
<template><div class="card-list"><Cardv-for="item in paginatedList":key="item.id":cardData="item"@card-click="handleCardClick"/><div v-if="loading" class="loading">加载中...</div></div>
</template><script>
import Card from './Card.vue'export default {name: 'CardList',components: { Card },props: {dataList: {type: Array,required: true}},data() {return {pageSize: 10,currentPage: 1,loading: false}},computed: {paginatedList() {return this.dataList.slice(0, this.currentPage * this.pageSize)}},mounted() {window.addEventListener('scroll', this.onScroll)},beforeDestroy() {window.removeEventListener('scroll', this.onScroll)},methods: {handleCardClick(card) {this.$emit('card-click', card)},onScroll() {const scrollBottom = window.innerHeight + window.scrollY >= document.body.offsetHeight - 10if (scrollBottom && !this.loading && this.canLoadMore) {this.loadNextPage()}},loadNextPage() {this.loading = truesetTimeout(() => {this.currentPage++this.loading = false}, 1000) // 模拟加载延迟}},computed: {canLoadMore() {return this.paginatedList.length < this.dataList.length}}
}
</script><style scoped>
.card-list {display: flex;flex-wrap: wrap;gap: 16px;
}.loading {width: 100%;text-align: center;padding: 16px;color: #999;font-style: italic;
}
</style>
Card.vue
(点击内部触发)
<template><div class="card" @click="handleClick"><h3>{{ cardData.title }}</h3><p>{{ cardData.description }}</p></div>
</template><script>
export default {name: 'Card',props: {cardData: {type: Object,required: true}},methods: {handleClick() {this.$emit('card-click', this.cardData)}}
}
</script><style scoped>
.card {border: 1px solid #ccc;padding: 16px;border-radius: 8px;cursor: pointer;width: 200px;transition: box-shadow 0.2s;
}
.card:hover {box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
}
</style>
总结:
这是一个基于 Vue 2 开发的可复用卡片列表组件,支持以下功能:
- 分页加载:初始显示部分数据,滚动到底部自动加载更多;
- 懒加载机制:通过监听页面滚动事件实现无限加载;
- 点击交互:每个卡片可点击,事件由卡片内部触发并向上传递;
- 加载状态显示:加载新数据时展示“加载中…”提示;