Actions, Getters và Modules trong Pinia

Tạo bởi Hoàng Vũ, chỉnh sửa cuối lúc 19 tháng 4, 2025

Ở bài trước, bạn đã học cách tạo một store đơn giản trong Pinia. Trong bài này, ta sẽ mở rộng kiến thức bằng cách làm quen với actions (hàm thao tác dữ liệu), getters (biến tính toán phụ thuộc state) và cách tách nhiều store theo module như auth, cart, user, v.v... Đây là kỹ thuật cốt lõi để tổ chức logic rõ ràng, dễ bảo trì trong các dự án thực tế.

Actions, Getters và Modules trong Pinia

1. Getters: Tạo biến tính toán từ state

  • Tương tự như computed – tự động cập nhật khi state thay đổi.
  • Truy cập qua store.getterName.

Ví dụ: Tổng số sản phẩm trong giỏ hàng

const totalItems = computed(() => cart.value.length)

Hoặc trong store:

export const useCartStore = defineStore('cart', () => {
  const items = ref([])

  const totalItems = computed(() => items.value.length)

  return { items, totalItems }
})

2. Actions: Thao tác với state

  • Tương tự như methods trong component.
  • Dùng để thêm, sửa, xoá, gọi API, thao tác bất đồng bộ.
const addItem = (item) => {
  items.value.push(item)
}

Hoặc async action:

const fetchCart = async () => {
  const res = await fetch('/api/cart')
  items.value = await res.json()
}

3. Tách store theo module (auth, cart, user...)

  • Mỗi file .ts là một module độc lập trong thư mục stores/.

auth store – stores/auth.ts:

export const useAuthStore = defineStore('auth', () => {
  const user = ref(null)
  const isLoggedIn = computed(() => !!user.value)

  const login = async (credentials) => { ... }

  return { user, isLoggedIn, login }
})

cart store – stores/cart.ts:

export const useCartStore = defineStore('cart', () => {
  const items = ref([])

  const add = (product) => items.value.push(product)
  const remove = (id) => items.value = items.value.filter(p => p.id !== id)
  const total = computed(() => items.value.reduce((t, p) => t + p.price, 0))

  return { items, add, remove, total }
})

4. Thực hành: Tạo store giỏ hàng

Step-by-step:

  1. Tạo file stores/cart.ts
  2. Thêm các biến items, total, addItem, removeItem
  3. Dùng trong component:
<script setup>
const cart = useCartStore()
</script>

<template>
  <div v-for="item in cart.items" :key="item.id">
    {{ item.name }} - {{ item.price }}
    <button @click="cart.remove(item.id)">Xoá</button>
  </div>
  <p>Tổng tiền: {{ cart.total }}</p>
</template>

Kết luận

Thông qua bài học này, bạn đã hiểu rõ về getters, actions và cách tách module để quản lý logic riêng biệt theo từng chức năng trong ứng dụng. Đây là nền tảng quan trọng giúp bạn xây dựng các ứng dụng lớn với cấu trúc dễ bảo trì, mở rộng. Trong bài kế tiếp, chúng ta sẽ tìm hiểu cách reactive hóa store và tích hợp Composition API nâng cao.

Website Logo

Với hơn 10 năm kinh nghiệm lập trình web và từng làm việc với nhiều framework, ngôn ngữ như PHP, JavaScript, React, jQuery, CSS, HTML, CakePHP, Laravel..., tôi hy vọng những kiến thức được chia sẻ tại đây sẽ hữu ích và thiết thực cho các bạn.

Bình luận

Website Logo

Chào, tôi là Vũ. Đây là blog hướng dẫn lập trình của tôi.

Liên hệ công việc qua email dưới đây.

lhvuctu@gmail.com

Chúng Tôi Trên

Bạn đang muốn học về lập trình website?

Bạn cần nâng cao kiến thức chuyên nghiệp hơn để nâng cao cơ hội nghề nghiệp? Liên hệ