iT邦幫忙

2024 iThome 鐵人賽

DAY 21
1
JavaScript

不會 VueUse 而被提分手的我系列 第 21

D-21 用 useInfiniteScroll - 來升級電商前端分頁的瀏覽吧

  • 分享至 

  • xImage
  •  

我自己的學習過程就像無限滾動的頁面一樣,我的學習沒有終點,每一個新技能都像是新內容隨著滾動展現。透過不斷學習,我開始理解得越來越深,無論是 useInfiniteScroll 還是其他 VueUse 的功能。
https://ithelp.ithome.com.tw/upload/images/20241004/20162115UFid5E3QrE.png

引言

在上一篇文章(D-18 用 useOffsetPagination - 來實現電商前端分頁吧)中,我們討論了如何使用 useOffsetPagination 實現前端分頁。然而,在手機上,不斷點擊『下一頁』的按鈕可能不太方便。今天,我們將探討如何使用 VueUse 的 useInfiniteScroll 來實現無限滾動載入,提供更流暢的使用者體驗。

  1. 什麼是無限滾動?
    • 簡短解釋無限滾動的概念
    • 無限滾動vs傳統分頁的優缺點
  2. 使用 useInfiniteScroll
    • 基本用法介紹
    • 參數說明
  3. 實現無限滾動載入商品列表
    • 修改現有的商品列表程式碼
    • 實現 loadMore 函式
    • 設定觸發 Dom
  4. 優化使用者體驗
    • 添載入入的提示
    • 處理沒新資料的情境
  5. 延伸還可以做的事

範例程式碼 (線上 Playground

<template>
  <div class="container mx-auto p-4">
    <!-- 原有的商品列表程式碼 -->
    <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
      <!-- 商品卡片 -->
    </div>

    <!-- 無限滾動觸發 Dom -->
    <div ref="loadMoreTrigger">
      <span v-if="canLoadMore">載入中...</span>
      <span v-else>已經到最底部了喔</span>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue';
import { useInfiniteScroll } from '@vueuse/core';

// ... 其他原有的程式碼 ...

const loadMoreTrigger = ref(null);
const canLoadMore = computed(() => productList.value.length < state.value.length);

useInfiniteScroll(
  loadMoreTrigger,
  async () => {
    // 模擬每次載入兩個商品
    await new Promise(resolve => setTimeout(resolve, 1000));
    const newItems = JSON.parse(JSON.stringify(state.value)).splice(
      productList.value.length,
      2
    );
    productList.value.push(...newItems);
  },
  { distance: 10, canLoadMore: () => canLoadMore.value }
);
</script>

  1. 什麼是無限滾動?

    簡短解釋無限滾動的概念:
    無限滾動是一種網頁設計技術,當使用者滾動到頁面底部時,自動載入更多內容。這創造了一種內容似乎無窮無盡的錯覺,讓使用者能持續滾動來瀏覽更多資訊。

    無限滾動 vs 傳統分頁的優缺點:

    優點:

    1. 提升使用者體驗:使用者可以流暢地瀏覽內容,無需手動點擊「下一頁」按鈕。
    2. 增加內容參與度:使用者能更自然地沉浸於內容中,進而瀏覽更多項目。
    3. 適合移動設備:在小螢幕上更易操作,無需精確點擊小按鈕。

    缺點:

    1. 效能問題:隨著載入的內容增加,頁面可能變得緩慢。
    2. 定位特定內容困難:使用者可能難以重新找到先前瀏覽過的項目。
    3. SEO 挑戰:搜尋引擎可能無法索引全部內容。
  2. 使用 useInfiniteScroll

    基本用法介紹:
    useInfiniteScroll 是 VueUse 庫提供的一個組合式函式,用於實現無限滾動功能。

    import { useInfiniteScroll } from '@vueuse/core'
    
    const el = ref(null)
    const data = ref([])
    
    useInfiniteScroll(
      el,
      () => {
        // 載入更多資料的邏輯
      },
      { distance: 10 }
    )
    
    

    參數說明:

    • 第一個參數:要監聽滾動的 Dom(通常是一個 ref)。
    • 第二個參數:當觸發滾動載入時執行的回調函式。
    • 第三個參數(可選):配置選項,如 distance(觸發距離)、direction(滾動方向)等。
  3. 實現無限滾動載入商品列表

    修改現有的商品列表程式碼:

    <template>
      <div class="container mx-auto p-4">
        <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
          <div v-for="product in productList" :key="product.id">
            <!-- 商品卡片內容 -->
          </div>
        </div>
        <div ref="loadMoreTrigger"></div>
      </div>
    </template>
    
    

    實現 loadMore 函式:

    const loadMore = async () => {
      if (isLoading.value || !canLoadMore.value) return;
    
      isLoading.value = true;
      const newProducts = await fetchProducts({
        limit: 10,
        offset: productList.value.length
      });
      productList.value.push(...newProducts);
      isLoading.value = false;
    };
    
    

    設置觸發 Dom:

    const loadMoreTrigger = ref(null);
    
    useInfiniteScroll(
      loadMoreTrigger,
      loadMore,
      { distance: 10, canLoadMore: () => canLoadMore.value }
    );
    
    
  4. 優化使用者體驗

    添載入入指示器:

    <template>
      <!-- 商品列表 -->
      <div v-if="isLoading" class="loading-indicator">
        載入中...
      </div>
    </template>
    
    

    處理無更多資料的情況:

    <template>
      <div v-if="!canLoadMore" class="no-more-data">
        已經到底了
      </div>
    </template>
    
    
  5. 延伸還可以做的事

    1. 錯誤處理與重試機制

    在實現無限滾動時,錯誤處理是一個關鍵考量。網路請求可能失敗,因此我們需要妥善處理這些情況。

    1. 防抖動(Debounce)

      為了避免快速滾動時觸發過多請求,我們可以使用防抖動。

    2. 虛擬滾動(Virtual Scrolling)

      當處理大量資料時,虛擬滾動能顯著提高效能。雖然useInfiniteScroll本身不提供虛擬滾動功能,但我們可以結合其他函式庫(如 vue-virtual-scroller)來實現這個功能。

    今天就到這邊拉~電商優化的系列到一個段落,如果有其他想看的也歡迎留言許願喔~


上一篇
D-20 useInfiniteScroll 解析與動機 -了解何謂無限
下一篇
D-22 useClipboard 文件說明與範例
系列文
不會 VueUse 而被提分手的我30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言