vue3 infinite scroll

This commit is contained in:
Cindy Chang
2024-06-24 09:07:11 +08:00
parent 9b0d54bf5e
commit b55cc0a6d6
4 changed files with 90 additions and 46 deletions

View File

@@ -9,7 +9,7 @@
<SearchBar/>
</div>
<div id="acct_mgmt_data_grid" class="flex w-full overflow-y-auto h-[570px]" @scroll="handleScroll">
<DataTable :value="internalInfiniteAcctData" dataKey="username" tableClass="w-full mt-4 text-sm relative table-fixed"
<DataTable :value="infiniteAcctData" dataKey="username" tableClass="w-full mt-4 text-sm relative table-fixed"
:rowClass="getRowClass"
>
<Column field="username" :header="i18next.t('AcctMgmt.Account')" bodyClass="font-medium" sortable>
@@ -149,7 +149,8 @@ export default {
const modalStore = useModalStore();
const { isLoading } = storeToRefs(loadingStore);
const loginStore = piniaLoginStore();
const internalInfiniteAcctData = ref([]);
const infiniteAcctData = ref([]);
const infiniteStart = ref(0);
const loginUserData = ref(null);
const allUserAccoutList = computed(() => acctMgmtStore.allUserAccoutList);
@@ -161,13 +162,13 @@ export default {
const moveCurrentLoginUserToFirstRow = () => {
const currentLoginUsername = loginUserData.value.username;
if(internalInfiniteAcctData.value && internalInfiniteAcctData.value.length){
const index = internalInfiniteAcctData.value.findIndex(user => user.username === currentLoginUsername);
if(infiniteAcctData.value && infiniteAcctData.value.length){
const index = infiniteAcctData.value.findIndex(user => user.username === currentLoginUsername);
if (index !== -1) {
// 移除匹配的對象(現正登入的使用者)並將其插入到陣列的第一位"
const [user] = internalInfiniteAcctData.value.splice(index, 1);
internalInfiniteAcctData.value.unshift(user);
const [user] = infiniteAcctData.value.splice(index, 1);
infiniteAcctData.value.unshift(user);
}
}
};
@@ -179,7 +180,7 @@ export default {
const getFirstPageUserData = async() => {
await acctMgmtStore.getAllUserAccounts();
internalInfiniteAcctData.value = allUserAccoutList.value.slice(0, ONCE_RENDER_NUM_OF_DATA)
infiniteAcctData.value = allUserAccoutList.value.slice(0, ONCE_RENDER_NUM_OF_DATA)
};
const isInfiniteFinish = ref(true);
@@ -234,34 +235,45 @@ export default {
/**
* 無限滾動: 監聽 scroll 有沒有滾到底部
* @param {element} event 滾動傳入的事件
scrollTop表示容器的垂直滾動位置。具體來說它是以像素為單位的數值
表示當前內容視窗(可見區域)的頂部距離整個可滾動內容的頂部的距離。
簡單來說scrollTop 指的是滾動條的位置當滾動條在最上面時scrollTop 為 0
當滾動條向下移動時scrollTop 會增加。
可是作為:我們目前已經滾動了多少。
clientHeight表示容器的可見高度不包括滾動條的高度。它是以像素為單位的數值
表示容器內部的可見區域的高度。
與 offsetHeight 不同的是clientHeight 不包含邊框、內邊距和滾動條的高度,只計算內容區域的高度。
scrollHeight表示容器內部的總內容高度。它是以像素為單位的數值
包括看不見的(需要滾動才能看到的)部分。
簡單來說scrollHeight 是整個可滾動內容的總高度,包括可見區域和需要滾動才能看到的部分。
*/
const handleScroll = (event) => {
if(internalInfiniteAcctData.value.length < ONCE_RENDER_NUM_OF_DATA || isInfiniteFinish.value === false) {
return;
}
const container = event.target;
const smallValue = 4;
const smallValue = 3;
const overScrollHeight = container.scrollTop + container.clientHeight >= container.scrollHeight - smallValue;
if(overScrollHeight){
const isOverScrollHeight = container.scrollTop + container.clientHeight >= container.scrollHeight - smallValue;
if(isOverScrollHeight){
fetchMoreDataVue3();
}
};
const fetchMoreDataVue3 = () => {
infiniteStart.value += ONCE_RENDER_NUM_OF_DATA;
internalInfiniteAcctData.value = [internalInfiniteAcctData.value, acctMgmtStore.allUserAccoutList.slice(
infiniteStart.value, this.infiniteStart + ONCE_RENDER_NUM_OF_DATA)];
isInfiniteFinish.value = true;
if(infiniteAcctData.value.length < acctMgmtStore.allUserAccoutList.length) {
infiniteAcctData.value = [...infiniteAcctData.value, ...acctMgmtStore.allUserAccoutList.slice(
infiniteStart.value, infiniteStart.value + ONCE_RENDER_NUM_OF_DATA)];
}
};
return {
isLoading,
modalStore,
loginUserData,
internalInfiniteAcctData,
infiniteAcctData,
onCreateNewClick,
handleScroll,
getRowClass,
@@ -286,7 +298,7 @@ export default {
return {
i18next: i18next,
repeatedAccountList: repeatedAccountList,
infiniteAcctData: [],
infiniteAcctDataVue2: [],
infiniteStart: 0,
isInfiniteFinish: true,
isInfinitMaxItemsMet: false,
@@ -311,7 +323,7 @@ export default {
* @param {element} event 滾動傳入的事件
*/
handleScrollVue2(event) {
if(this.infinitMaxItems || this.infiniteAcctData.length < ONCE_RENDER_NUM_OF_DATA || this.isInfiniteFinish === false) {
if(this.infinitMaxItems || this.infiniteAcctDataVue2.length < ONCE_RENDER_NUM_OF_DATA || this.isInfiniteFinish === false) {
return;
}
@@ -332,7 +344,7 @@ export default {
this.infiniteFinish = false;
this.infiniteStart += ONCE_RENDER_NUM_OF_DATA;
// await this.acctMgmtStore.getAccountDetail();
this.infiniteAcctData = await [...this.infiniteAcctData, ...this.allUserAccoutList.slice(
this.infiniteAcctDataVue2 = await [...this.infiniteAcctDataVue2, ...this.allUserAccoutList.slice(
this.infiniteStart, this.infiniteStart + ONCE_RENDER_NUM_OF_DATA)];
this.isInfiniteFinish = true;
this.isLoading = false;