代码示例:
import { defineStore } from "pinia"; // 导入 Pinia 的 defineStore 方法
import { ref } from "vue"; // 导入 Vue 的响应式 API ref
import { type Menu } from "@/interface"; // 导入自定义的 Menu 类型// 创建一个名为 'userMenu' 的 Store
const useUserMenuStore = defineStore("userMenu", // Store 的唯一标识名() => { // 使用组合式 API 的 setup 函数写法// 1. 定义当前菜单状态(响应式引用)const menu = ref<Menu[]>([]); // 创建一个存储 Menu 数组的响应式引用// 2. 设置菜单的方法const setMenu = (newMenu: Menu[]) => {menu.value = newMenu; // 更新菜单数据};// 3. 清除菜单的方法const removeMenu = () => {menu.value = []; // 清空当前菜单pastMenu.value = []; // 同时清空历史菜单};// 4. 定义历史菜单状态(响应式引用)const pastMenu = ref<Menu[]>([]); // 创建一个存储历史菜单的响应式引用// 5. 设置历史菜单的方法const setPastMenu = (newMenu: Menu[]) => {pastMenu.value = newMenu; // 更新历史菜单数据};// 暴露所有需要外部访问的状态和方法return { menu, setMenu, removeMenu, pastMenu, setPastMenu };},{ persist: true } // 启用持久化插件配置(页面刷新后数据不丢失)
);export default useUserMenuStore; // 导出 Store
核心概念解释:
-
defineStore:
-
Pinia 的核心方法,用于创建 Store
-
第一个参数是 Store 的唯一名称
-
第二个参数是 setup 函数,用组合式 API 编写
-
第三个参数是配置对象,这里启用了持久化
-
-
ref:
-
Vue 的响应式 API,用于创建响应式数据
-
ref<Menu[]>
表示这是一个存储 Menu 类型数组的响应式引用 -
通过
.value
访问/修改值(但在模板中会自动解包,不需要 .value)
-
-
类型系统:
-
Menu
是自定义类型(来自 @/interface) -
TypeScript 泛型
<Menu[]>
确保数据类型的正确性
-
-
方法功能:
-
setMenu:更新当前菜单
-
removeMenu:清空所有菜单数据
-
setPastMenu:更新历史菜单
-
-
持久化配置:
-
{ persist: true }
表示启用状态持久化 -
需要配合 pinia-plugin-persistedstate 插件使用
-
数据会保存在 localStorage 中,防止页面刷新丢失
-
使用场景示例:
javascript
// 在组件中使用 import useUserMenuStore from '@/stores/userMenu';const menuStore = useUserMenuStore();// 更新菜单 menuStore.setMenu([{ id: 1, name: '首页' }]);// 获取当前菜单 console.log(menuStore.menu); // 清空菜单 menuStore.removeMenu();
新手需要注意:
-
响应式规则:
-
在 JS 中修改状态需要使用
.value
-
在模板中直接使用变量名即可
-
-
Store 的生命周期:
-
单例模式:整个应用共享同一个 Store 实例
-
持久化数据会一直保留,直到手动清除或用户清除浏览器缓存
-
-
类型安全:
-
TypeScript 的类型约束可以帮助减少错误
-
如果传递错误类型的参数,编译时会报错
-
这个 Store 的设计非常适合管理需要持久化的全局界面状态(比如用户菜单、主题设置等),通过分离状态逻辑使组件更专注于视图渲染。