资讯动态

v3-admin-vite Pinia Store 开发规范:从 Setup Store 语法到持久化模式的完整实践指南

发布时间:2026/10/4 10:25:07 来源:尧图企业网站定制
前端【免费下载链接】v3-admin-vite☀️ AI-friendly Vue3 admin template | Vue Admin | Vue Template | Vue3 Admin | Vue3 Template | Vue 后台 | Vue 模板 | Vue3 后台 | Vue3 模板项目地址https://gitcode.com/gh_mirrors/v3a/v3-admin-vite点击查看免费下载本指南以 v3-admin-vite 的 AI 辅助开发 Skill.agents/skills/v3-upsert-store/SKILL.md为骨架系统讲解该项目中创建与更新全局状态Pinia Store的完整规范。你将掌握 Setup Store 语法、useXxxStoreOutside约定、CacheKey localStorage 持久化模式、命名约定与文件结构顺序等一整套可直接落地执行的规则并能对照仓库内的真实 Store 实现如 user.ts、app.ts、tags-view.ts验证每一项约定。一、何时触发该 Skill创建或更新全局状态v3-upsert-store是 v3-admin-vite 项目中面向 AI Agent 与开发者的一套「新增或更新 Pinia Store」操作规范。当用户提出以下任一场景时都应触发新建状态管理新增 Pinia Store给已有 Store 加字段。即使用户没有明确说出「Store」只要意图与状态管理器相关就应使用本 Skill。触发后需要用户提供三部分输入Store 名称如counter、notification——决定文件名、Store ID 与 Composable 命名State 字段列表——每个字段需明确字段名英文camelCase、类型string / number / boolean / array / object / 自定义类型、初始值以及是否需要持久化到 localStorageActions 描述——需要哪些操作如 reset、toggle、increment、fetch 等。如果用户信息不完整应主动询问补全后再生成避免凭空臆造字段类型与行为。本 Skill 定义的是项目默认 Store 模式当用户的实际需求与本 Skill 约定冲突时以用户需求为准。二、操作模式创建与更新的两种路径2.1 创建新 Store当src/pinia/stores/store名.ts不存在时生成完整的 Store 文件。仓库中所有 Store 均位于 src/pinia/stores 目录下目前已有app.ts、permission.ts、settings.ts、tags-view.ts、user.ts五个实例。2.2 更新已有 Store当文件已存在时在已有代码中追加新的 State 字段和 Actions保留原有代码不动。追加规则新 State 声明插入到已有 State 声明之后新 Actions 插入到已有 Actions 之后如有// #region分组则放在对应区域更新return语句追加新导出的字段和方法。以 tags-view.ts 为例它正是这一模式的典型体现多个同类型的操作addVisitedView/addCachedView、delVisitedView/delCachedView、delOthersVisitedViews/delOthersCachedViews、delAllVisitedViews/delAllCachedViews被组织进四个// #region add、// #region del、// #region delOthers、// #region delAll分区中每个区域的操作都通过return语句统一导出。三、生成文件与持久化配套生成 Store 的核心文件路径为src/pinia/stores/store名.ts。持久化相关文件仅在用户指定了持久化字段时才生成共涉及两处配套修改在 src/common/constants/cache-key.ts 的CacheKey类中追加新的 Key在 src/common/utils/local-storage.ts 中追加对应的 get/set 函数。这两个文件是整个项目持久化体系的基础所有 localStorage 的 Key 统一收敛在CacheKey类中所有读写操作统一收敛在local-storage.ts工具模块中Store 内部不会出现散落的localStorage.getItem/setItem调用。四、Store 文件结构模板Setup Store 语法完整的 Store 文件结构如下以一个带持久化和辅助函数的 Store 为例import type { XxxType } from /types/xxx import { getXxx, setXxx } from /utils/local-storage import { pinia } from /pinia interface Sidebar { opened: boolean withoutAnimation: boolean } /** 辅助函数的用途描述 */ function helperFunction(param: string) { // ... } export const useXxxStore defineStore(xxx, () { // Token const token refstring(getToken() || ) // 侧边栏状态 const sidebar: Sidebar reactive({ opened: true, withoutAnimation: false }) // 设置 Token const setToken (value: string) { token.value value } // 切换侧边栏 const toggleSidebar (withoutAnimation: boolean) { sidebar.opened !sidebar.opened sidebar.withoutAnimation withoutAnimation } return { token, sidebar, setToken, toggleSidebar } }) /** * description 在 SPA 应用中可用于在 pinia 实例被激活前使用 store * description 在 SSR 应用中可用于在 setup 外使用 store */ export function useXxxStoreOutside() { return useXxxStore(pinia) }这个模板与仓库中的真实实现高度一致。对比 app.ts用reactive管理sidebar: Sidebar结构openedwithoutAnimation两个紧密关联的字段toggleSidebar与closeSidebar均为箭头函数 Action文件末尾同样导出useAppStoreOutside并保留完全相同的 JSDoc 注释。4.1 关键规则清单必须使用 Setup Store 语法defineStore(id, () { ... })不使用 Options API必须导出useXxxStoreOutside函数且 JSDoc 注释原样保留见上方模板defineStore第一个参数Store ID单词用小写如user多词用 kebab-case如tags-viewState 类型标注ref用泛型refstring()、refnumber(0)、refstring[]([])reactive在变量上标注类型const sidebar: Sidebar reactive({...})Actions 统一使用箭头函数const xxx (param: Type) { ... }注释风格Store 内部的 State 和 Actions 用//单行注释描述具体用途如// 切换侧边栏、// 设置 Token不要使用/** */JSDoc 注释 Store 内部成员不要使用泛化的分区标题如// state、// actions每条注释直接描述对应内容模块级辅助函数Store 外部使用/** */JSDoc 注释// #region/// #endregion仅在同一类操作有多组变体时使用如 tags-view 的 add/del/delOthers/delAll普通 Store 不需要自动导入defineStore、ref、reactive、watch、watchEffect、computed无需手动 importVue 类型导入是允许的如import type { Ref } from vue。仓库中的 user.ts 就是规则 1、3、4、5 的完整示范Store ID 为usertoken refstring(getToken() || )使用泛型标注所有 ActionsetToken、getInfo、changeUser、logout、resetToken、resetTagsView均为箭头函数并用// 设置 Token、// 获取用户详情等单行注释说明用途。4.2 文件结构顺序1. import type 语句类型导入 2. import 语句运行时导入Pinia 实例必须导入 3. interface / type 声明Store 需要的本地类型 4. 模块级辅助函数不需要响应式访问的纯函数用 /** */ 注释 5. export const useXxxStore defineStore(...) 6. export function useXxxStoreOutside()对照 permission.tsimport type { RouteRecordRaw }类型导入→import { pinia } from /pinia运行时导入→interface UserPermissionInfo本地类型→hasPermission/filterDynamicRoutes两个模块级纯函数 →defineStore→usePermissionStoreOutside顺序完全一致。五、持久化模式CacheKey localStorage 工具函数当字段需要持久化时遵循项目既有三步模式。5.1 CacheKey 常量在 src/common/constants/cache-key.ts 的CacheKey类中追加static readonly XXX_DATA ${SYSTEM_NAME}-xxx-data-key命名规则大写下划线 -key后缀。所有 Key 均以SYSTEM_NAME值为v3-admin-vite为前缀避免不同项目之间的缓存 Key 冲突。仓库现有 Key 包括TOKEN、CONFIG_LAYOUT、SIDEBAR_STATUS、ACTIVE_THEME_NAME、VISITED_VIEWS、CACHED_VIEWS全部遵循${SYSTEM_NAME}-xxx-key模式。5.2 localStorage 工具函数在 src/common/utils/local-storage.ts 中追加并使用// #region Xxx 描述分组。简单字符串值// #region Xxx 描述 export function getXxx() { return localStorage.getItem(CacheKey.XXX_DATA) } export function setXxx(value: string) { localStorage.setItem(CacheKey.XXX_DATA, value) } // #endregion对象/数组值// #region Xxx 描述 export function getXxx() { const json localStorage.getItem(CacheKey.XXX_DATA) return json ? (JSON.parse(json) as XxxType) : null } export function setXxx(data: XxxType) { localStorage.setItem(CacheKey.XXX_DATA, JSON.stringify(data)) } // #endregion仓库中的 local-storage.ts 同时演示了两种形态getToken/setToken/removeToken处理简单字符串getLayoutsConfig/setLayoutsConfig与getVisitedViews/setVisitedViews则处理对象与数组后者还通过JSON.parse(json ?? [])提供默认值并在setVisitedViews中删除matched、redirectedFrom等属性防止JSON.stringify处理到循环引用——这是持久化路由对象时值得借鉴的防御性写法。5.3 Store 中使用import { getXxx, setXxx } from /utils/local-storage // Xxx 数据 const data refXxxType(getXxx() ?? defaultValue) // 监听变化并持久化 watch(data, (newVal) { setXxx(newVal) })当需要同时监听多个持久化字段时用watchEffect代替多个watchwatchEffect(() { setVisitedViews(visitedViews.value) setCachedViews(cachedViews.value) })5.4 仓库中的持久化实现对照app.ts 展示了「初始化读取 watch 回写」的完整闭环sidebar.opened初始值来自getSidebarStatus()随后watch(() sidebar.opened, ...)在状态变化时调用handleSidebarStatus写回本地缓存。tags-view.ts 则展示了watchEffect批量持久化的写法visitedViews与cachedViews两个字段在同一个watchEffect中统一写入本地存储同时以cacheTagsView来自useSettingsStore控制是否启用缓存未启用时初始值直接为空数组。settings.ts 提供了另一种高级形态通过映射类型SettingsStore { [Key in keyof LayoutsConfig]: RefLayoutsConfig[Key] }遍历layoutsConfig的全部键为每个键创建ref并挂载watch自动持久化从而以极少的样板代码把整个布局配置对象变成响应式 Store。六、类型定义规范简单类型直接在 Store 文件中用interface或type声明定义在 Store 函数之前需要被外部引用的类型加export如export type TagView PartialRouteLocationNormalizedGeneric见 tags-view.ts复杂、共享类型抽离到types目录或就近放置。app.ts 中的interface Sidebar是「本地简单类型」的示范而TagView因为被local-storage.ts等外部模块引用使用了export导出。七、命名约定以 Store 名为notification为例各位置的命名如下位置命名文件src/pinia/stores/notification.tsStore IDnotificationComposableuseNotificationStoreOutsideuseNotificationStoreOutsideCacheKey如需NOTIFICATION_DATAlocalStorage 函数如需getNotificationData/setNotificationData多词 Store 名使用 kebab-case 文件名和 Store ID如user-preference→user-preference→useUserPreferenceStore。仓库中的tags-view正是这一约定的实际案例。八、导入规范// 类型导入 import type { Ref } from vue import type { RouteRecordRaw } from vue-router // 运行时导入常量和工具函数 import { SIDEBAR_CLOSED, SIDEBAR_OPENED } from /constants/app-key import { getSidebarStatus, setSidebarStatus } from /utils/local-storage // 运行时导入Pinia 实例必需 import { pinia } from /pinia // 运行时导入其他 Store当需要跨 Store 交互时 import { useSettingsStore } from ./settings导入顺序规则类型导入在前运行时导入在后路径在前路径在后。注意与是两个不同的别名对应src/common目录对应src根目录。仓库中 user.ts 的导入顺序与此完全吻合先是/apis/users、/utils/local-storage再是/pinia、/router最后是相对路径的同级 Store。九、设计决策指引ref vs reactive— 当 State 是一个有结构的对象且字段间关联紧密时用reactive如 sidebar 的openedwithoutAnimation否则每个独立状态用ref。大多数情况下用ref。watch vs watchEffect— 监听单个字段变化时用watch监听多个字段且都需要持久化时用watchEffect自动追踪依赖代码更简洁。辅助函数放在 Store 内还是外— 不依赖响应式状态的纯逻辑函数放在 Store 外部如权限过滤、格式化需要访问 Store 内ref/reactive的函数放在内部作为 Action。permission.ts中的hasPermission、filterDynamicRoutes是前者tags-view.ts中操作visitedViews.value的addVisitedView等是后者。是否需要 Reset Action— 如果 Store 管理的是临时状态如表单数据、UI 状态通常需要一个 Reset 方法恢复初始值如果是用户身份等持久数据通常不需要通用 Reset。注意 user.ts 中的resetToken是一个特例它并非通用 Reset而是登出流程中针对 Token 与用户信息的安全重置。是否需要 Outside 函数— 始终生成。这是项目约定确保在路由守卫、Axios 拦截器等 setup 外场景可用。仓库中全部五个 Store 都导出了对应的useXxxStoreOutside如 user.ts 的useUserStoreOutside其内部通过useXxxStore(pinia)显式传入在 src/pinia/index.ts 中创建的pinia实例。十、Outside 函数的使用场景useXxxStoreOutside的核心价值在于脱离组件 setup 上下文使用 Store。典型的应用场景包括路由守卫在 src/router/guard.ts 等位置获取用户权限或登录态Axios 拦截器在 src/http/axios.ts 中读取或重置 TokenSSR 场景在 setup 外读取响应式状态。在 SPA 应用中它可用于在 pinia 实例被激活前使用 store在 SSR 应用中它可用于在 setup 外使用 store——这正是该函数 JSDoc 注释所描述的双重用途。十一、与其他 Skill 的协作边界在 v3-admin-vite 的 .agents/skills 目录下v3-upsert-store与v3-upsert-route、v3-create-crud、v3-use-composables、v3-use-utils共同构成一套完整的功能开发约定。实际开发中边界清晰新增状态→ 使用v3-upsert-store本文所述规范新增路由页面→ 使用v3-upsert-route新增增删改查模块→ 使用v3-create-crud复用既有 Composable / 工具函数→ 优先检查v3-use-composables与v3-use-utils是否已有现成能力避免重复造轮子。当新增模块同时涉及状态、路由与接口时可先按各自 Skill 约定依次落地最后在return语句与路由注册处完成收口。总结v3-upsert-store 的规范核心可以浓缩为六句话文件放在src/pinia/stores/必须用 Setup Store 语法必须导出useXxxStoreOutsideStore ID 用 kebab-caseref用泛型、reactive标类型、Action 用箭头函数内部注释用//模块级辅助函数用 JSDoc持久化必须经过CacheKey与local-storage.ts的统一封装多字段用watchEffect批量监听。对照仓库内 app.ts、user.ts、tags-view.ts、settings.ts 与 permission.ts 五个真实 Store每一项约定都能找到对应实现是团队协作与 AI 辅助编码时保持状态管理代码风格统一的可执行标准。赞分享前端【免费下载链接】v3-admin-vite☀️ AI-friendly Vue3 admin template | Vue Admin | Vue Template | Vue3 Admin | Vue3 Template | Vue 后台 | Vue 模板 | Vue3 后台 | Vue3 模板项目地址https://gitcode.com/gh_mirrors/v3a/v3-admin-vite点击查看免费下载相关推荐Fantastic-admin 框架 Pinia Store 生成指南从交互式建模到持久化与自动导入的完整实践Fantastic admin 框架 Pinia Store 生成指南从交互式建模到持久化与自动导入的完整实践 Store状态仓库是管理系统中承载全局共前端AI 技能Fantastic-admin 框架 Pinia Store 开发指南模板、持久化与自动导入实战Fantastic admin 框架 Pinia Store 开发指南模板、持久化与自动导入实战 本篇指南围绕 Fantastic admin 管理系统中 P前端AI 技能Fantastic-admin 框架 Pinia Store 生成指南从需求分析到持久化实战Fantastic admin 框架 Pinia Store 生成指南从需求分析到持久化实战 本文基于 Fantastic adminGitHub Tren前端AI 技能上一篇容器镜像版本管理Kitematic标签功能深度解析下一篇QtScrcpy 完整指南5 分钟把手机投屏到电脑并反向控制创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑