Giới thiệu Vuex / Pinia

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

Trong các ứng dụng Vue.js lớn, việc quản lý trạng thái (state) giữa các Component trở nên phức tạp. Vuex và Pinia là hai thư viện giúp giải quyết vấn đề này bằng cách cung cấp một store tập trung để quản lý state.

Mục tiêu bài học:

  • Hiểu VuexPinia là gì, tại sao cần quản lý state toàn cục.
  • So sánh Vuex vs Pinia: Điểm mạnh, điểm yếu và khi nào nên sử dụng.
  • Hướng dẫn cài đặttích hợp Vuex / Pinia vào dự án Vue.
  • Thực hành: Tạo store đơn giản bằng cả Vuex và Pinia.

Vuex / Pinia

1. Vuex / Pinia là gì? Tại sao cần quản lý state toàn cục?

Vấn đề khi không có Vuex / Pinia
Giả sử bạn có một ứng dụng Vue có nhiều Component và cần chia sẻ dữ liệu giữa chúng. Nếu chỉ sử dụng props (truyền dữ liệu từ cha -> con) hoặc event emitting (gửi dữ liệu từ con -> cha), code sẽ nhanh chóng trở nên phức tạp và khó bảo trì khi ứng dụng lớn dần.

Giải pháp: Sử dụng Vuex hoặc Pinia

  • Vuex và Pinia giúp lưu trữ state toàn cục, cho phép bất kỳ Component nào trong ứng dụng truy cập hoặc cập nhật dữ liệu mà không cần truyền props hay emit event.
  • Điều này giúp dễ bảo trì, tái sử dụng và tối ưu hóa hiệu suất ứng dụng.

2. So sánh Vuex với Pinia: Khi nào nên dùng cái nào?

Tiêu chí Vuex Pinia
Cấu trúc Dựa trên Mutations, Actions, Getters Sử dụng trực tiếp State, Getters, Actions
Hỗ trợ TypeScript Hỗ trợ nhưng hơi phức tạp Hỗ trợ mạnh mẽ, dễ dùng
API Phức tạp hơn (Mutations cần để cập nhật state) Dễ hiểu, đơn giản, không cần Mutations
Hiệu suất Không tối ưu bằng Pinia Tối ưu hóa tốt hơn (chỉ cập nhật phần state cần thiết)
Tích hợp với Vue DevTools Có, hiển thị chi tiết hơn
Dành cho dự án nào? Dự án lớn, có nhiều quy trình logic phức tạp Dự án vừa và nhỏ hoặc những ai muốn code đơn giản hơn

Kết luận:

  • Vuex phù hợp cho các dự án lớn, cần logic phức tạp và quản lý state nhiều module.
  • Pinia đơn giản hơn, hiệu suất tốt hơn, thích hợp cho dự án mới hoặc thay thế Vuex trong Vue 3.

3. Cách cài đặt và tích hợp Vuex / Pinia vào dự án Vue

Cài đặt Vuex (Vue 2 & Vue 3):

npm install vuex

Cài đặt Pinia (Vue 3):

npm install pinia

Thực hành: Tạo store đơn giản với Vuex và Pinia

1. Tạo Store đơn giản với Vuex

Bước 1: Tạo file store.js

import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment(state) {
      state.count++;
    }
  },
  actions: {
    increment({ commit }) {
      commit("increment");
    }
  },
  getters: {
    doubleCount: state => state.count * 2
  }
});

Bước 2: Import vào main.js

import Vue from "vue";
import App from "./App.vue";
import store from "./store"; // Import Vuex store

Vue.config.productionTip = false;

new Vue({
  store, // Thêm store vào Vue instance
  render: h => h(App)
}).$mount("#app");

Bước 3: Sử dụng Vuex store trong Component Counter.vue

<template>
  <div>
    <h1>Count: {{ count }}</h1>
    <h2>Double Count: {{ doubleCount }}</h2>
    <button @click="increment">Tăng</button>
  </div>
</template>

<script>
import { mapState, mapGetters, mapActions } from "vuex";

export default {
  computed: {
    ...mapState(["count"]),
    ...mapGetters(["doubleCount"])
  },
  methods: {
    ...mapActions(["increment"])
  }
};
</script>

2. Tạo Store đơn giản với Pinia

Bước 1: Tạo file store/counter.js

import { defineStore } from "pinia";

export const useCounterStore = defineStore("counter", {
  state: () => ({
    count: 0
  }),
  getters: {
    doubleCount: (state) => state.count * 2
  },
  actions: {
    increment() {
      this.count++;
    }
  }
});

Bước 2: Import vào main.js

import { createApp } from "vue";
import { createPinia } from "pinia";
import App from "./App.vue";

const app = createApp(App);
app.use(createPinia()); // Kích hoạt Pinia
app.mount("#app");

Bước 3: Sử dụng Pinia store trong Component Counter.vue

<template>
  <div>
    <h1>Count: {{ counter.count }}</h1>
    <h2>Double Count: {{ counter.doubleCount }}</h2>
    <button @click="counter.increment">Tăng</button>
  </div>
</template>

<script>
import { useCounterStore } from "../store/counter";
import { storeToRefs } from "pinia";

export default {
  setup() {
    const counter = useCounterStore();
    const { count, doubleCount } = storeToRefs(counter);

    return { counter, count, doubleCount };
  }
};
</script>

Kết luận

Tóm tắt kiến thức quan trọng:

  • Vuex / Pinia giúp quản lý state toàn cục, giảm phức tạp khi truyền dữ liệu giữa các Component.
  • Vuex phù hợp cho dự án lớn với cấu trúc chặt chẽ.
  • Pinia nhẹ hơn, đơn giản hơn, phù hợp cho dự án Vue 3 và dễ sử dụng.
  • Thực hành: Xây dựng store đơn giản với cả Vuex và Pinia.
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ệ