Optimizing State Management with Pinia in Large-Scale Vue Applications

Best practices for implementing Pinia as the state management solution in complex Vue projects, focusing on scalability and maintainability.

0 likes
9 views

Rule Content

# Title: Optimizing State Management with Pinia in Large-Scale Vue Applications
# Description: Best practices for implementing Pinia as the state management solution in complex Vue projects, focusing on scalability and maintainability.
# Category: Vue Cursor Rules

rules:
  - id: pinia-modular-store-design
    description: "Ensure Pinia stores are modular to enhance scalability and maintainability."
    severity: warning
    pattern: |
      export const use{{storeName}}Store = defineStore('{{storeName}}', {
        state: () => ({
          // state properties
        }),
        // actions and getters
      });
    condition: |
      // Check if the store contains unrelated state properties or lacks modular separation
      const stateKeys = Object.keys(state);
      return stateKeys.some(key => /* logic to detect unrelated properties */);
    fix: |
      // Suggest splitting the store into multiple, focused stores
      // Example:
      export const useUserStore = defineStore('user', {
        state: () => ({
          user: null,
          preferences: {},
        }),
        // actions and getters
      });

      export const useCartStore = defineStore('cart', {
        state: () => ({
          items: [],
          total: 0,
        }),
        // actions and getters
      });

  - id: pinia-getters-for-derived-state
    description: "Use getters in Pinia stores to compute derived state instead of storing computed values."
    severity: warning
    pattern: |
      export const use{{storeName}}Store = defineStore('{{storeName}}', {
        state: () => ({
          // state properties
        }),
        getters: {
          // getter functions
        },
      });
    condition: |
      // Check if the store contains state properties that should be computed
      const stateKeys = Object.keys(state);
      return stateKeys.some(key => /* logic to detect computed properties stored in state */);
    fix: |
      // Suggest moving computed properties to getters
      // Example:
      export const useCartStore = defineStore('cart', {
        state: () => ({
          items: [],
        }),
        getters: {
          total: (state) => state.items.reduce((sum, item) => sum + item.price, 0),
          itemCount: (state) => state.items.length,
        },
      });

  - id: pinia-action-composition
    description: "Avoid unnecessary splitting of actions in Pinia stores to maintain code clarity and coherence."
    severity: warning
    pattern: |
      export const use{{storeName}}Store = defineStore('{{storeName}}', {
        actions: {
          // action functions
        },
      });
    condition: |
      // Check if the store contains actions that are overly split
      const actionKeys = Object.keys(actions);
      return actionKeys.some(key => /* logic to detect unnecessary action splitting */);
    fix: |
      // Suggest consolidating related actions into a single action
      // Example:
      export const useCheckoutStore = defineStore('checkout', {
        actions: {
          async completeCheckout() {
            await this.validateCart();
            await this.processPayment();
            // Additional checkout logic...
          },
        },
      });

  - id: pinia-lazy-loading
    description: "Implement lazy loading of Pinia store modules to improve performance in large-scale applications."
    severity: warning
    pattern: |
      import { defineStore } from 'pinia';
      export const use{{storeName}}Store = defineStore('{{storeName}}', {
        // store definition
      });
    condition: |
      // Check if the store is imported and used without lazy loading
      return /* logic to detect non-lazy-loaded store imports */;
    fix: |
      // Suggest implementing lazy loading for the store
      // Example:
      const useCartStore = defineStore('cart', {
        // store definition
      });

      // In the component
      const cartStore = useCartStore();

  - id: pinia-persisted-state
    description: "Use plugins or middleware to persist Pinia store state across sessions, ensuring data is not lost on page reloads."
    severity: warning
    pattern: |
      import { defineStore } from 'pinia';
      export const use{{storeName}}Store = defineStore('{{storeName}}', {
        // store definition
      });
    condition: |
      // Check if the store lacks state persistence implementation
      return /* logic to detect absence of state persistence */;
    fix: |
      // Suggest implementing state persistence using a plugin
      // Example:
      import { createPinia } from 'pinia';
      import { useStorage } from '@vueuse/core';

      const pinia = createPinia();
      pinia.use(({ store }) => {
        store.$subscribe((mutation, state) => {
          useStorage(store.$id, state);
        });
      });

      export const useCartStore = defineStore('cart', {
        // store definition
      });