Trong quá trình phát triển ứng dụng với Uniapp, việc hiển thị danh sách dữ liệu và cho phép người dùng tải thêm là tính năng phổ biến. Làm thế nào để mặc định hiển thị n dòng đầu tiên, sau đó mỗi lần nhấn nút "Tải thêm" lại tăng thêm n dữ liệu mới? Bài viết này sẽ hướng dẫn bạn cách triển khai cơ chế đó trong Uniapp một cách chi tiết.
Mã nguồn hoàn chỉnh
<template>
<view class="container">
<view class="listWrapper">
<view class="header">
Đã mời <text>{{ totalItems }}</text> người
</view>
<view class="itemBox" v-for="(record, idx) in filteredList" :key="idx">
<view class="rowContent" v-show="isExpanded || idx < displayLimit">
<view class="userInfo">
<image :src="record.avatar"></image>
<text class="name">{{ record.name }}</text>
</view>
<text class="date">{{ record.date }}</text>
</view>
</view>
<view class="loadMoreBtn" v-show="totalItems >= displayLimit" @tap="loadMore">Xem thêm</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
displayLimit: 3, // Số dòng hiển thị mặc định
isExpanded: false,
totalItems: 6,
fakeData: [
{ name: "Người dùng 1", date: "2022-08-01", avatar: "/static/avatar.png" },
{ name: "Người dùng 2", date: "2022-08-02", avatar: "/static/avatar.png" },
{ name: "Người dùng 3", date: "2022-08-03", avatar: "/static/avatar.png" },
{ name: "Người dùng 4", date: "2022-08-04", avatar: "/static/avatar.png" },
{ name: "Người dùng 5", date: "2022-08-05", avatar: "/static/avatar.png" },
{ name: "Người dùng 6", date: "2022-08-06", avatar: "/static/avatar.png" }
]
};
},
computed: {
filteredList() {
return this.fakeData;
}
},
methods: {
loadMore() {
this.displayLimit += 1; // Mỗi lần nhấn thêm 1 dòng
}
}
};
</script>
<style scoped>
.container { background: #fdd52f; padding: 16px; margin: 16px; }
.listWrapper { background: #fef7e5; border-radius: 6px; }
.header { display: flex; justify-content: center; color: #ffab02; padding-top: 10px; }
.rowContent { display: flex; justify-content: space-between; align-items: center; padding: 10px; }
.rowContent image { border-radius: 50%; width: 30px; height: 30px; }
.userInfo { display: flex; align-items: center; }
.name { padding-left: 10px; }
.loadMoreBtn { display: flex; justify-content: center; color: #9d9d9d; padding-bottom: 10px; font-size: 14px; }
</style>
Biến thể: Mở rộng toàn bộ hoặc thu gọn
Ở phiên bản thứ hai, chúng ta có thể chuyển đổi giữa hiển thị một phần và toàn bộ danh sách bằng một nút bấm duy nhất.
<template>
<view class="container">
<view class="listWrapper">
<view class="header">Đã mời <text>{{ totalItems }}</text> người</view>
<view v-for="(record, idx) in fakeData" :key="idx">
<view class="rowContent" v-show="isExpanded || idx < displayLimit">
<view class="userInfo">
<image :src="record.avatar"></image>
<text class="name">{{ record.name }}</text>
</view>
<text class="date">{{ record.date }}</text>
</view>
</view>
<view class="loadMoreBtn" v-show="!isExpanded && fakeData.length > displayLimit" @click="isExpanded = true">Mở rộng</view>
<view class="loadMoreBtn" v-show="isExpanded && fakeData.length > displayLimit" @click="isExpanded = false">Thu gọn</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
displayLimit: 1,
totalItems: 6,
isExpanded: false,
fakeData: [
{ name: "Người dùng 1", date: "2022-08-01", avatar: "/static/avatar.png" },
{ name: "Người dùng 2", date: "2022-08-02", avatar: "/static/avatar.png" },
{ name: "Người dùng 3", date: "2022-08-03", avatar: "/static/avatar.png" },
{ name: "Người dùng 4", date: "2022-08-04", avatar: "/static/avatar.png" },
{ name: "Người dùng 5", date: "2022-08-05", avatar: "/static/avatar.png" },
{ name: "Người dùng 6", date: "2022-08-06", avatar: "/static/avatar.png" }
]
};
}
};
</script>
Với cách triển khai này, bạn có thể dễ dàng điều chỉnh số lượng dòng hiển thị ban đầu (displayLimit) và số lần tải thêm tùy theo yêu cầu dự án. Biến thể thứ hai phù hợp khi bạn muốn người dùng có thể mở rộng hoặc thu gọn danh sách thay vì tải dần từng phần.