Cách triển khai Infinite Scrolling trong Vue

Infinite Scrolling hữu ích khi bạn cần hiện khối dữ liệu lớn trong ứng dụng. Ở bài viết này, hãy cùng nhau học cách tạo Infinite Scrolling - load vô tận trong Vue nhé!

Cuộn vô tận trong Vue

Infinite Scrolling là một kỹ thuật mà bạn có thể dùng để hiện nhiều nội dung hơn khi người dùng app cuộn xuống dưới trang. Nó loại bỏ nhu cầu phân trang, đồng thời cho phép người dùng app tiếp tục cuộn hay tải qua các tập dữ liệu lớn.

Thiết lập ứng dụng Vue

Để làm theo hướng dẫn này, bạn cần có kiến thức cơ bản về Vue 3 và JavaScript. Bạn nên biết cách xử lý các truy vấn HTTP với Axios.

Để bắt đầu học cách triển khai cuộn vô tận, tạo một app Vue mới bằng cách chạy lệnh npm sau trong thư mục ưa thích của bạn:

npm create vue

Trong khi thiết lập dự án, Vue sẽ nhắc bạn chọn một preset cho ứn dụng. Chọn No cho tất cả tính năng, vì bạn sẽ không cần thêm chúng vào ứng dụng.

Tạo Vue

Sau khi đã tạo app mới, điều hướng tới thư mục của ứng dụng và chạy lệnh npm sau để cài các gói cần thiết:

npm install axios @iconify/vue @vueuse/core

Lệnh npm cài 3 package: axios (cho truy vấn HTTP), @iconify/vue (để tích hợp icon dễ dàng trong Vue) và @vueuse/core (cung cấp các tính năng Vue cần thiết).

Bạn sẽ dùng axios @iconify/vue để tìm nạp dữ liệu và thêm icon vào ứng dụng. @vueuse/core chứa các tiện ích Vue, bao gồm thành phần useInfiniteScroll để có được load vô tận.

Tìm nạp dummy data từ JSONPlaceholder API

Để triển khai chức năng infinite scrolling, bạn cần dữ liệu. Bạn có thể mã hóa cứng dữ liệu hoặc lấy dữ liệu từ nguồn API giả miễn phí như JSONPlaceholder.

Lấy những dữ liệu này từ JSONPlaceholder mô phỏng các tình huống thực tế, bởi hầu hết ứng dụng web đều lấy dữ liệu từ database thay cho dữ liệu code cứng.

Để tìm nạp dữ liệu từ API cho ứng dụng Vue, tạo thư mục mới trong danh mục src và đặt tên nó là api. Trong thư mục đó, tạo file JavaScript mới và dán code sau:

//getComments.js

import axios from "axios";

async function getComments(max, omit) {
  try {
    const comments = await axios.get(
      `https://jsonplaceholder.typicode.com/comments?_limit=${max}&_start=${omit}`
    );
    return comments.data.map((comment) => comment.body);
  } catch (error) {
    console.error(error);
  }
}

export default getComments;

Đoạn code này bao gồm một hàm không đồng bộ để lấy bình luận từ endpoint API “https://jsonplaceholder.typicode.com/comments”. Sau đó nó sẽ xuất hàm này.

Giải thích kỹ hơn, đoạn code bắt đầu bằng việc nhập thư viện axios. Sau đó, code này xác định hàm getComments với hai đối số: max và omit.

Hàm getComments chứa phương thức axios.get() mà tạo truy vấn GET cho URL. URL này chứa các tham số truy vấn max và omit, được nội suy trong chuỗi bằng cách sử dụng ký tự mẫu (``). Điều này cho phép bạn chuyển các giá trị động vào URL.

Hàm này sau đó trả về một mảng mới chứa body của các bình luận đã nhận từ endpoint API bằng hàm map.

Nếu có bất kỳ lỗi xảy ra, đoạn code này ghi lại nó vào console. Đoạn code sau đó xuất hàm này vào phần khác của ứng dụng.

Tạo thành phần Infinite Scroll

Giờ bạn đã xử ls logic cho tìm nạp dữ liệu mẫu (dummy data), bạn có thể tạo một thành phần mới để hiện dummy data và xử lý chức năng load vô hạn.

Tạp file mới InfiniteScroll.vue trong thư mục src/components và thêm code sau:

<!-- InfiniteScroll.vue -->
<script setup>
import { ref } from "vue";
import getComments from "../api/getComments";
import { useInfiniteScroll } from "@vueuse/core";

const listEl = ref(null);

const commentsDisplayed = 20;
const commentsList = ref(await getComments(commentsDisplayed, 0));

const commentsToDisplayOnScroll = async () => {
  const newComments = await getComments(
    commentsDisplayed,
    commentsList.value.length
  );

  commentsList.value.push(...newComments);
};

useInfiniteScroll(
  listEl,
  async () => {
    await commentsToDisplayOnScroll();
  },
  { distance: 10 }
);
</script>

Đoạn code trên mô tả khối tập lệnh của thành phần InfiniteScroll.

Đoạn code này nhập các hàm ref useInfiniteScroll từ vue@vueuse/core tương ứng. Đoạn code cũng nhập hàm getComments từ file getComments.js.

Sau đó, đoạn này tạo một tham chiếu listEl với hàm ref. listEl tham chiếu phần tử DOM với hàm cuộn load vô tận.

Biến commentsDisplayed đại diện cho số bình luận sẽ hiển thị ban đầu trên tang. commentsList chứa mảng bình luận mà đoạn code tìm bằng hàm getComments.

Đoạn này chứa hàm bất đồng bộ commentsToDisplayOnScroll có chức năng tìm bình luận mới với hàm getComments và nối chúng vào mảng commentsList bằng toán tử mở rộng (…).

Cuối cùng, đoạn code này gọi hàm useInfiniteScroll để kích hoạt tác vụ cuộn vô tận nhận 3 đối số:

  • Thành phần DOM (listEl) đại diện cho danh sách mà người dùng ứng dụng sẽ cuộn qua.
  • Hàm async gọi khi người dùng cuộn để kích hoạt tìm nạp nhận xét mới và nối chúng vào commentsList.
  • Một đối tượng cấu hình tùy chọn với các thuộc tính. Đối tượng { distance: 10 } chỉ định rằng các nhận xét mới sẽ bắt đầu tải khi người dùng cách 10 pixel tính từ cuối danh sách.

Sử dụng thành phần Infinite Scroll

Sau khi xử lý logic load vô tận trong khối tập lệnh của InfiniteScroll, bạn cần hiện nội dung trong khối mẫu.

Dán code sau vào trong thành phần InfiniteScroll:

<!-- InfiniteScroll.vue -->
<template>
  <div>
    <ul ref="listEl">
      <li v-for="comment in commentsList">
        {{ comment }}
      </li>
    </ul>
  </div>
</template>

Khối code này xác định mẫu cho thành phần Vue chịu trách nhiệm hiện một danh sách bình luận.

Thành phần <ul> chứa bộ sưu tập các thành phần <li> được tạo bằng lệnh v-for (để hiện danh sách), lặp qua mảng commentsList.

Mỗi bình luận từ mảng được hiện trong thành phần <li> dùng nội suy dữ liệu ({{ comment }}). Khối code này gán tham chiếu listEl cho <ul> để kích hoạt hàm cuộn vô tận.

Sau đó, bạn có thể dùng thành phần InfiniteScroll trong file App.vue.

<!-- App.vue -->

<script setup>
import InfiniteScroll from "./components/InfiniteScroll.vue";
import { Icon } from "@iconify/vue";
</script>

<template>
  <Suspense>
    <InfiniteScroll />
    <template #fallback>
      <Icon icon="eos-icons:bubble-loading" width="250" height="250" />
    </template>
  </Suspense>
</template>

Khối code trên nhập thành phần InfiniteScroll và Icon. Sau đó, nó gói InfiniteScroll vào trong Suspense.

Thành phần Suspense cho phép bạn hiện nội dung dự phòng (một icon) khi Vue giải quyết tất cả các chức năng không đồng bộ trong thành phần InfiniteScroll.

Giờ bạn có thể xem trước ứng dụng bằng cách chạy lệnh npm run dev trong thư mục của ứng dụng. Bạn sẽ thấy một giao diện tương tự như ảnh bên dưới:

Cửa sổ xem trước

Cửa sổ xem trước ở trên hiện 10 bình luận vì bạn đặt biến commentsToBeDisplayed là 10. Khi cuộn xuống dưới, app tải nhiều bình luận hơn để đọc.

Kỹ thuật cuộn vô tận phổ biến trong số các ứng dụng web, nhất là ở những app mạng xã hội như X, TikTok..

Kỹ thuật này đảm bảo người dùng app luôn tương tác vì ứng dụng liên tục tìm nạp thêm dữ liệu, cung cấp cho họ luồng nội dung ngày càng mở rộng để đọc, tìm hiểu và xem, nhờ đó họ luôn cảm thấy hào hứng khi lướt trên trang.

Thứ Năm, 17/08/2023 14:40
51 👨 170
0 Bình luận
Sắp xếp theo