tansci/.claude/skills/fa-store-generator/references/store-patterns.md
xuewuerduo f468d532b1 feat: 初始化tansci资产管理项目
包含以下模块:
- antdv-next-admin: Vue 3 + TypeScript + Ant Design Vue 管理后台
  - 设备/许可证/配件/耗材 CRUD 管理页面
  - 基础数据管理 (分类/位置/制造商/型号/供应商)
  - 业务管理 (故障报修/盘点/资产分配/资产申请/交易记录)
  - 下拉选项改造 (ID输入框 → 搜索下拉选择)
  - 资产状态字典化 (接入sys_dict系统)
  - 界面文案优化 (设备→资产, 在库/在用/维修中/已报废)
  - 修复 console 警告 (popupClassName, 重复组件注册)
- our-itam: Java Spring Boot + magic-api 后端服务
- fantastic-admin: 前端底层框架 (pnpm monorepo)
- ciyo-itasset: CIYO 资产模块
- magic-script-skill: Claude Code skill 定义
- .claude: 对话历史记录

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-05-17 21:41:22 +08:00

3.9 KiB
Raw Blame History

Store 模板与示例

基础模板

import { defineStore } from 'pinia'

export const use<Name>Store = defineStore('<id>', () => {
  // State
  const <field> = ref<<Type>>(<initialValue>)

  // Computed
  const <computed> = computed(() => ...)

  // Actions
  function <action>() {
    ...
  }

  return {
    <field>,
    <computed>,
    <action>,
  }
})

模板变体

1. 纯状态 Store无持久化、无异步

import { defineStore } from 'pinia'

export const useCartStore = defineStore('cart', () => {
  const items = ref<CartItem[]>([])
  const visible = ref(false)

  const total = computed(() =>
    items.value.reduce((sum, item) => sum + item.price * item.quantity, 0),
  )

  function addItem(item: CartItem) {
    const existing = items.value.find(i => i.id === item.id)
    if (existing) {
      existing.quantity++
    }
    else {
      items.value.push({ ...item, quantity: 1 })
    }
  }

  function removeItem(id: string) {
    items.value = items.value.filter(i => i.id !== id)
  }

  function clear() {
    items.value = []
  }

  return { items, visible, total, addItem, removeItem, clear }
})

2. 带持久化的 Store

import { defineStore } from 'pinia'

export const useUserPreferenceStore = defineStore(
  'userPreference',
  () => {
    const theme = ref<'light' | 'dark'>('light')
    const language = ref('zh-cn')
    const pageSize = ref(20)

    function setTheme(val: 'light' | 'dark') {
      theme.value = val
    }

    return { theme, language, pageSize, setTheme }
  },
  {
    persist: {
      pick: ['theme', 'language', 'pageSize'],  // 只持久化指定字段
    },
  },
)

持久化默认使用 localStoragekey 为 store ID。 使用 pick 只持久化部分字段,避免持久化临时状态。

3. 带异步 Action 的 Store

import { defineStore } from 'pinia'

export const useNotificationStore = defineStore('notification', () => {
  const list = ref<Notification[]>([])
  const loading = ref(false)
  const unreadCount = computed(() => list.value.filter(n => !n.read).length)

  async function fetchList() {
    loading.value = true
    try {
      const res = await api.notification.list()
      list.value = res.data
    }
    finally {
      loading.value = false
    }
  }

  async function markRead(id: string) {
    await api.notification.markRead(id)
    const item = list.value.find(n => n.id === id)
    if (item) {
      item.read = true
    }
  }

  return { list, loading, unreadCount, fetchList, markRead }
})

4. 带 TypeScript 接口定义的 Store

import { defineStore } from 'pinia'

interface DictionaryItem {
  label: string
  value: string | number
}

interface DictionaryState {
  [key: string]: DictionaryItem[]
}

export const useDictionaryStore = defineStore('dictionary', () => {
  const data = ref<DictionaryState>({})

  function getItems(type: string): DictionaryItem[] {
    return data.value[type] ?? []
  }

  async function fetchByType(type: string) {
    if (data.value[type]) return  // 已缓存,跳过
    const res = await api.dictionary.getByType(type)
    data.value[type] = res.data
  }

  return { data, getItems, fetchByType }
})

项目现有 Store 参考

Store 文件 用途
useAppAccountStore modules/app/account.ts 登录/登出、token、多账号
useAppSettingsStore modules/app/settings.ts 主题、语言、布局配置
useAppMenuStore modules/app/menu.ts 菜单生成与导航状态
useAppTabbarStore modules/app/tabbar.ts 标签栏管理

注意事项

  • Store 文件放在 src/store/modules/ 后,unplugin-auto-import 会自动扫描并全局注入,无需手动 import
  • Store ID 必须全局唯一camelCase
  • 避免在 store 中直接引用 DOM 或组件实例
  • 跨 store 调用:直接在 setup 函数内调用其他 storeconst authStore = useAppAccountStore()