要使用 Pinia 实现一个模块化设计的图书管理系统,我们可以将系统的不同功能模块拆分为独立的 Store,例如用户管理、图书管理、借阅管理等。以下是具体实现步骤:


1. 项目初始化

首先,确保你的项目已经安装了 Pinia:

npm install pinia

main.ts 中初始化 Pinia:

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

const pinia = createPinia();
const app = createApp(App);

app.use(pinia);
app.mount('#app');

2. 模块化 Store 设计

将图书管理系统的功能拆分为多个 Store,例如:

(1) 用户管理模块 (userStore)

// stores/user.ts
import { defineStore } from 'pinia';

export const useUserStore = defineStore('user', {
  state: () => ({
    id: 0,
    name: '未登录用户',
    role: 'guest', // 角色:guest, user, admin
  }),
  actions: {
    login(user: { id: number; name: string; role: string }) {
      this.id = user.id;
      this.name = user.name;
      this.role = user.role;
    },
    logout() {
      this.id = 0;
      this.name = '未登录用户';
      this.role = 'guest';
    },
  },
});

(2) 图书管理模块 (bookStore)

// stores/book.ts
import { defineStore } from 'pinia';

export const useBookStore = defineStore('book', {
  state: () => ({
    books: [] as { id: number; title: string; author: string; stock: number }[],
  }),
  actions: {
    addBook(book: { title: string; author: string; stock: number }) {
      this.books.push({ id: this.books.length + 1, ...book });
    },
    removeBook(id: number) {
      this.books = this.books.filter((book) => book.id !== id);
    },
    updateStock(id: number, stock: number) {
      const book = this.books.find((book) => book.id === id);
      if (book) book.stock = stock;
    },
  },
  getters: {
    availableBooks: (state) => state.books.filter((book) => book.stock > 0),
  },
});

(3) 借阅管理模块 (borrowStore)

// stores/borrow.ts
import { defineStore } from 'pinia';

export const useBorrowStore = defineStore('borrow', {
  state: () => ({
    borrowRecords: [] as { userId: number; bookId: number; borrowDate: string; returnDate: string | null }[],
  }),
  actions: {
    borrowBook(userId: number, bookId: number) {
      this.borrowRecords.push({ userId, bookId, borrowDate: new Date().toISOString(), returnDate: null });
    },
    returnBook(userId: number, bookId: number) {
      const record = this.borrowRecords.find(
        (record) => record.userId === userId && record.bookId === bookId && !record.returnDate
      );
      if (record) record.returnDate = new Date().toISOString();
    },
  },
  getters: {
    userBorrowRecords: (state) => (userId: number) =>
      state.borrowRecords.filter((record) => record.userId === userId),
  },
});

3. 在组件中使用 Store

在组件中,可以根据需要引入并使用不同的 Store。例如,在图书管理页面:

<template>
  <div>
    <h1>图书管理</h1>
    <ul>
      <li v-for="book in bookStore.availableBooks" :key="book.id">
        {{ book.title }} - {{ book.author }} (库存: {{ book.stock }})
      </li>
    </ul>
  </div>
</template>

<script setup>
import { useBookStore } from '@/stores/book';

const bookStore = useBookStore();
</script>

在借阅页面:

<template>
  <div>
    <h1>借阅记录</h1>
    <ul>
      <li v-for="record in borrowStore.userBorrowRecords(userStore.id)" :key="record.bookId">
        图书ID: {{ record.bookId }} - 借阅日期: {{ record.borrowDate }}
      </li>
    </ul>
  </div>
</template>

<script setup>
import { useBorrowStore } from '@/stores/borrow';
import { useUserStore } from '@/stores/user';

const borrowStore = useBorrowStore();
const userStore = useUserStore();
</script>

4. 跨 Store 调用

Pinia 允许在一个 Store 中调用另一个 Store 的状态或方法。例如,在 borrowStore 中调用 bookStore 的方法:

// stores/borrow.ts
import { defineStore } from 'pinia';
import { useBookStore } from './book';

export const useBorrowStore = defineStore('borrow', {
  actions: {
    borrowBook(userId: number, bookId: number) {
      const bookStore = useBookStore();
      const book = bookStore.books.find((book) => book.id === bookId);
      if (book && book.stock > 0) {
        this.borrowRecords.push({ userId, bookId, borrowDate: new Date().toISOString(), returnDate: null });
        bookStore.updateStock(bookId, book.stock - 1);
      }
    },
  },
});

5. 持久化存储

为了在页面刷新后保持状态,可以使用 pinia-plugin-persistedstate 插件:

npm install pinia-plugin-persistedstate

main.ts 中配置插件:

import { createApp } from 'vue';
import { createPinia } from 'pinia';
import App from './App.vue';
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate';

const pinia = createPinia();
pinia.use(piniaPluginPersistedstate);

const app = createApp(App);
app.use(pinia);
app.mount('#app');

在 Store 中启用持久化:

export const useUserStore = defineStore('user', {
  state: () => ({
    id: 0,
    name: '未登录用户',
    role: 'guest',
  }),
  persist: true,
});

6. 总结

通过模块化设计,我们将图书管理系统的功能拆分为独立的 Store,每个 Store 负责管理特定的业务逻辑。这种设计不仅使代码更清晰,还提高了可维护性和可扩展性。希望这篇教程能帮助你实现一个高效的图书管理系统!