0
0
Lập trình
NM

Tạo Biến Thể Sản Phẩm Bằng JavaScript Cơ Bản

Đăng vào 5 tháng trước

• 6 phút đọc

Giới Thiệu

Bạn đã bao giờ tự hỏi làm thế nào các trang thương mại điện tử quản lý tất cả các biến thể có thể của một sản phẩm chưa? Một chiếc áo thun có thể có 4 kích cỡ, 5 màu sắc và 3 kiểu dáng. Việc liệt kê tất cả các biến thể này một cách thủ công sẽ là một cơn ác mộng.

Trong bài viết này, chúng ta sẽ xây dựng một thành phần tương tác sạch sẽ bằng JavaScript cơ bản để giải quyết vấn đề này. Nó sẽ nhận một tập hợp các tùy chọn và tạo ra mọi kết hợp có thể một cách động, cập nhật theo thời gian thực khi bạn thực hiện các lựa chọn.

Mục Lục

1. HTML: Một Nền Tảng Đơn Giản

Đầu tiên, chúng ta cần một cấu trúc cơ bản để chứa các tùy chọn và kết quả. HTML rất đơn giản: hai thẻ chứa là tất cả những gì chúng ta cần.

html Copy
<!doctype html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="./index.css" rel="stylesheet">
    <script type="module" src="./permutations.js"></script>
</head>
<body>
    <div class="p-8 bg-gray-50 min-h-screen">
        <div class="max-w-4xl mx-auto">
            <header class="mb-8">
                <h1 class="text-3xl font-bold">Biến Thể Sản Phẩm</h1>
                <p class="text-gray-600">Chọn tùy chọn để xem tất cả các kết hợp có thể.</p>
            </header>
            <div id="options-container" class="space-y-6"></div>
            <div class="mt-10 pt-6 border-t">
                <h2 class="text-2xl font-semibold">Kết Quả Kết Hợp</h2>
                <div id="results-container" class="p-4 mt-4 bg-white rounded-lg shadow-sm"></div>
            </div>
        </div>
    </div>
</body>
</html>

2. Dữ Liệu: Cấu Trúc Các Tùy Chọn

Trước khi viết bất kỳ logic nào, chúng ta cần một cách sạch sẽ để đại diện cho các tùy chọn sản phẩm. Một mảng đối tượng là hoàn hảo cho điều này. Mỗi đối tượng đại diện cho một danh mục (như "Kích cỡ") và chứa các biến thể có thể.

javascript Copy
const optionsData = [
  {
    name: "Kích cỡ",
    variants: [
      { label: "Nhỏ", value: "Small", checked: true },
      { label: "Vừa", value: "Medium", checked: true },
      { label: "Lớn", value: "Large", checked: false },
    ],
  },
  {
    name: "Màu sắc",
    variants: [
      { label: "Xanh", value: "Blue", checked: true },
      { label: "Trắng", value: "White", checked: true },
    ],
  },
  {
    name: "Họa tiết",
    variants: [
      { label: "Trơn", value: "Plain", checked: true },
      { label: "Logo", value: "Logo", checked: false },
    ],
  },
];

Cấu trúc này dễ quản lý và mở rộng. Thuộc tính checked cho phép chúng ta đặt trạng thái mặc định.

3. Logic Chính: Bộ Nhận Biến Thể

Đây là nơi phép màu xảy ra. Mục tiêu của chúng ta là lấy các tùy chọn đã chọn và tạo ra tất cả các kết hợp. Chúng ta sẽ làm điều này với một hàm mạnh mẽ.

Bước 1: Lấy các biến thể đã chọn.

Chúng ta cần chuyển đổi optionsData thành một mảng đơn giản hơn, chỉ chứa value của các biến thể được chọn.

javascript Copy
function calculatePermutations() {
  const activeVariants = optionsData
    .map((option) =>
      option.variants.filter((v) => v.checked).map((v) => v.value)
    )
    .filter((arr) => arr.length > 0);

  // ...
}

Nếu "Nhỏ," "Vừa," "Xanh," và "Trơn" được chọn, activeVariants sẽ trông như thế này:
[['Small', 'Medium'], ['Blue'], ['Plain']]

Bước 2: Sử dụng reduce để tạo ra các kết hợp.

Bây giờ chúng ta sẽ sử dụng phương thức reduce để lặp qua activeVariants và xây dựng danh sách cuối cùng. reduce rất lý tưởng để lấy một mảng và "giảm" nó thành một giá trị duy nhất - trong trường hợp của chúng ta, một mảng cuối cùng của tất cả các kết hợp.

javascript Copy
const combinations = activeVariants.reduce((acc, current) => {
  if (acc.length === 0) {
    return current.map((item) => [item]);
  }
  const newCombinations = [];
  acc.forEach((accItem) => {
    current.forEach((currentItem) => {
      newCombinations.push([...accItem, currentItem]);
    });
  });
  return newCombinations;
}, []);

Hãy theo dõi nó:

  1. Lần gọi đầu tiên: acc[], current['Small', 'Medium']. Hàm trả về [['Small'], ['Medium']].
  2. Lần gọi thứ hai: acc[['Small'], ['Medium']], current['Blue']. Vòng lặp chạy và tạo ra [['Small', 'Blue'], ['Medium', 'Blue']].
  3. Lần gọi thứ ba: acc[['Small', 'Blue'], ['Medium', 'Blue']], current['Plain']. Vòng lặp chạy một lần nữa, cho chúng ta kết quả cuối cùng: [['Small', 'Blue', 'Plain'], ['Medium', 'Blue', 'Plain']].

4. Tương Tác Người Dùng: Các Hàm Giao Diện

Logic đã hoàn thành, nhưng chúng ta cần cho phép người dùng tương tác với nó. Chúng ta sẽ tạo ra các hàm để hiển thị các tùy chọn và kết quả.

Hàm renderOptions() lặp qua optionsData và tạo ra HTML cho các hộp kiểm. Quan trọng là nó thêm một listener sự kiện cho từng hộp kiểm.

javascript Copy
function renderOptions() {
  const optionsContainer = document.getElementById("options-container");
  optionsContainer.innerHTML = ""; // Xóa các tùy chọn trước

  optionsData.forEach((option, index) => {
    option.variants.forEach((variant) => {
      checkbox.addEventListener("change", (e) => {
        variant.checked = e.target.checked;
        renderOptions();
        calculatePermutations();
      });
    });
  });
}

Listener sự kiện change là chìa khóa. Nó cập nhật trạng thái checked trong optionsData và sau đó chạy lại các hàm hiển thị và tính toán. Điều này làm cho thành phần tương tác.

Cuối cùng, renderResults() chỉ cần lấy mảng từ calculatePermutations() và hiển thị nó dưới dạng danh sách.

javascript Copy
function renderResults(combinations) {
  const resultsContainer = document.getElementById("results-container");
  resultsContainer.innerHTML = ""; // Xóa kết quả cũ

  const list = document.createElement("ul");
  combinations.forEach((combo) => {
    const listItem = document.createElement("li");
    listItem.textContent = combo.join(" / ");
    list.appendChild(listItem);
  });
  resultsContainer.appendChild(list);
}

Kết Luận

Và đó là tất cả! Chúng ta đã xây dựng một bộ tạo biến thể mạnh mẽ, có thể tái sử dụng và tương tác chỉ với một vài hàm JavaScript cơ bản. Bằng cách kết hợp một cấu trúc dữ liệu sạch sẽ với sức mạnh của map, filter, và reduce, chúng ta đã giải quyết một vấn đề thực tế phức tạp một cách tinh tế.

Bạn sẽ sử dụng điều này trong các dự án của mình như thế nào? Hãy cho tôi biết trong phần bình luận bên dưới!

Câu Hỏi Thường Gặp

1. Cách sử dụng mã này trong dự án của tôi?
Bạn chỉ cần sao chép mã HTML và JavaScript vào dự án của mình và điều chỉnh theo nhu cầu.

2. Mã này có tương thích với các trình duyệt cũ không?
Mã JavaScript hiện tại sử dụng các tính năng hiện đại. Hãy đảm bảo rằng trình duyệt của bạn hỗ trợ ES6.

3. Có cách nào để tối ưu hóa hơn nữa không?
Có thể xem xét việc sử dụng thư viện bên ngoài cho việc quản lý trạng thái hoặc tối ưu hóa hiệu suất.

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào