Vue3 pinia模块化设计实战
要使用 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 负责管理特定的业务逻辑。这种设计不仅使代码更清晰,还提高了可维护性和可扩展性。希望这篇教程能帮助你实现一个高效的图书管理系统!
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 万家灯火