Aparência
Pinia na Prática
Ao usar o Pinia para gerenciar o estado em aplicações Vue.js com TypeScript, é importante seguir as melhores práticas para garantir a clareza do código, a reusabilidade e a manutenção fácil. Aqui estão alguns exemplos detalhados que demonstram como estruturar sua store Pinia de acordo com essas práticas:
1. Estruturação Básica da Store
Vamos começar com uma estrutura básica de store, usando TypeScript para definir explicitamente os tipos:
typescript
// src/stores/userStore.ts
import { defineStore } from "pinia";
interface UserState {
name: string;
email: string;
loggedIn: boolean;
}
export const useUserStore = defineStore("user", {
state: (): UserState => ({
name: "",
email: "",
loggedIn: false,
}),
getters: {
isAuthenticated(state: UserState): boolean {
return state.loggedIn;
},
},
actions: {
logIn(email: string, name: string) {
this.email = email;
this.name = name;
this.loggedIn = true;
},
logOut() {
this.$reset();
},
},
});
Explicação:
- State: Define as propriedades do estado com tipos específicos.
- Getters: Funções computadas baseadas no estado que também podem ser tipadas para garantir que retornem o tipo correto.
- Actions: Métodos para mudar o estado. Utilizamos
$reset
para redefinir o estado para seus valores iniciais, uma funcionalidade integrada do Pinia que ajuda a manter o estado consistente após o logout.
2. Uso de Store em Componentes
Com a store definida, aqui está como você pode usá-la em um componente Vue usando a Composition API:
vue
<script setup lang="ts">
import { useUserStore } from "@/stores/userStore";
const { name, logIn, logOut } = useUserStore();
</script>
<template>
<div>
<p v-if="isAuthenticated">Olá, {{ name }}!</p>
<button @click="logIn('user@example.com', 'User')">Log In</button>
<button @click="logOut" v-if="isAuthenticated">Log Out</button>
</div>
</template>
Explicação:
- O componente acessa a store usando a função
useUserStore()
. - Os métodos e estados da store são expostos diretamente no template do componente, permitindo seu uso como se fossem parte do componente.
3. Modularização e Reusabilidade
Para projetos maiores, pode ser útil dividir a store em módulos. O Pinia suporta a modularização naturalmente, permitindo que você mantenha partes do estado e lógica relacionados juntos, mas separados de outras partes da aplicação.
typescript
// src/stores/cartStore.ts
import { defineStore } from "pinia";
interface CartItem {
productId: string;
quantity: number;
}
interface CartState {
items: CartItem[];
}
export const useCartStore = defineStore("cart", {
state: (): CartState => ({
items: [],
}),
getters: {
totalQuantity(state: CartState): number {
return state.items.reduce((total, item) => total + item.quantity, 0);
},
},
actions: {
addToCart(productId: string, quantity: number) {
const existingItem = this.items.find(
(item) => item.productId === productId
);
if (existingItem) {
existingItem.quantity += quantity;
} else {
this.items.push({ productId, quantity });
}
},
removeFromCart(productId: string) {
this.items = this.items.filter((item) => item.productId !== productId);
},
},
});
Melhores Práticas:
- Isolamento de Estado: Mantenha o estado relacionado junto e isolado de outras partes da aplicação.
- Tipagem Forte: Use TypeScript para definir interfaces claras para seu estado e ações.
- Reusabilidade: Modularize o estado para reutilizá-lo em várias partes da aplicação sem redundância.
Seguir essas práticas ao usar o Pinia não só melhora a qualidade do código, mas também facilita a manutenção e escalabilidade da sua aplicação Vue.js.