store-pc
SKILL.md
前端状态管理指南
适用于: 腾云智慧食堂管理系统前端项目(Vue 2.7.16 + Vuex 3.4.0)
Store 目录:
/Users/xujiajun/Developer/frontProj/web/src/store/
目录结构
src/store/
├── index.js # Store 入口(Vuex 初始化)
├── getters.js # 全局 getters
└── modules/ # Store 模块(28个)
├── user.js # 用户状态(最核心)
├── app.js # 应用状态(语言/尺寸)
├── permission.js # 权限路由管理
├── tagsView.js # 标签页管理
├── settings.js # 系统设置
├── marketing.js # 营销状态
├── order.js # 订单状态
├── stock.js # 库存状态
├── reportcenter.js # 报表状态
├── account.js # 账户状态
├── purchase.js # 采购状态
├── chart.js # 图表状态
├── notice.js # 通知状态
├── upload.js # 上传状态
├── menudish.js # 菜品状态
├── supplyChain.js # 供应链状态
└── ... # 其他业务模块
全局 Getters(getters.js)
// 常用全局 getters(可直接用 mapGetters 访问)
{
token, // 登录 token
name, // 用户名
userInfo, // 完整用户信息对象
permissions, // 权限列表
hasRoles, // 是否已加载角色(用于路由守卫)
permission_routes, // 已生成的权限路由
adminMerchant, // 是否为超级管理员商户
url, // API base URL
language, // 当前语言(zh/en)
size, // Element UI 组件尺寸
areaOptions, // 区域选项(来自 supplyChain)
}
创建新 Store
标准模板
// src/store/modules/xxx.js
import { getList, getDetail } from '@/api/xxx'
const state = {
list: [],
current: null,
loading: false,
total: 0
}
const mutations = {
SET_LIST: (state, list) => {
state.list = list
},
SET_CURRENT: (state, current) => {
state.current = current
},
SET_LOADING: (state, loading) => {
state.loading = loading
},
SET_TOTAL: (state, total) => {
state.total = total
}
}
const actions = {
/**
* 获取列表
*/
async fetchList({ commit }, params) {
commit('SET_LOADING', true)
try {
const res = await getList({
page: { current: params.current || 1, size: params.size || 20 },
object: params
})
commit('SET_LIST', res.records || [])
commit('SET_TOTAL', res.total || 0)
return res
} finally {
commit('SET_LOADING', false)
}
},
/**
* 获取详情
*/
async fetchDetail({ commit }, id) {
const res = await getDetail({ id })
commit('SET_CURRENT', res)
return res
},
/**
* 重置状态
*/
reset({ commit }) {
commit('SET_LIST', [])
commit('SET_CURRENT', null)
commit('SET_TOTAL', 0)
}
}
const getters = {
list: state => state.list,
current: state => state.current,
loading: state => state.loading,
total: state => state.total
}
export default {
namespaced: true,
state,
mutations,
actions,
getters
}
在 index.js 中注册
// src/store/index.js
import xxx from './modules/xxx'
export default new Vuex.Store({
modules: {
// ... 其他模块
xxx
}
})
使用 Store
方式 1:直接访问
export default {
computed: {
list() {
return this.$store.state.xxx.list
},
loading() {
return this.$store.state.xxx.loading
},
// 使用全局 getter
token() {
return this.$store.getters.token
},
userInfo() {
return this.$store.getters.userInfo
}
},
methods: {
getData() {
this.$store.dispatch('xxx/fetchList', this.queryParams)
}
}
}
方式 2:mapState / mapGetters / mapActions
import { mapState, mapGetters, mapActions, mapMutations } from 'vuex'
export default {
computed: {
// 模块内 state
...mapState('xxx', ['list', 'loading', 'total']),
// 全局 getters
...mapGetters(['token', 'userInfo', 'permissions', 'adminMerchant'])
},
methods: {
...mapActions('xxx', ['fetchList', 'fetchDetail', 'reset']),
async getData() {
await this.fetchList({ ...this.queryParams, ...this.page })
}
},
mounted() {
this.getData()
}
}
核心 Store 模块说明
user.js(用户状态)
最重要的模块,包含:
state.token- 登录 tokenstate.userInfo- 完整用户信息(userId、roles、roleCode、merchantId 等)state.hasRoles- 是否已加载角色信息state.adminMerchant- 是否为超级管理员(roleCode === 'ROLE_ADMIN')state.merchantList- 商户列表(管理员可切换商户)
// 在路由守卫中获取用户信息
const userInfo = await store.dispatch('user/getInfo')
// 登出
await store.dispatch('user/resetToken')
localStorage.clear()
locationHref()
permission.js(权限路由)
- 根据用户角色动态生成路由
state.routes- 完整路由表(用于菜单渲染)state.addRoutes- 动态添加的路由
// 在路由守卫中生成权限路由
const accessRoutes = await store.dispatch('permission/generateRoutes')
accessRoutes.forEach(route => {
router.addRoute(route)
})
app.js(应用状态)
state.language- 当前语言(zh/en)state.size- Element UI 组件尺寸
最佳实践
1. 何时使用 Store
| 场景 | 是否使用 Store |
|---|---|
| 多个页面/组件共享的数据 | ✅ 使用 |
| 用户登录状态、权限 | ✅ 使用(user 模块) |
| 全局配置(语言、尺寸) | ✅ 使用(app 模块) |
| 页面内部状态(表单数据) | ❌ 用 data |
| 父子组件传值 | ❌ 用 props/emit |
| 兄弟组件通信(简单) | ❌ 用 eventBus |
2. 命名规范
// ✅ 正确:Mutation 大写字母+下划线
const mutations = {
SET_LIST: (state, list) => { state.list = list },
SET_LOADING: (state, v) => { state.loading = v }
}
// ✅ 正确:Action 小驼峰
const actions = {
fetchList: async ({ commit }, params) => { },
fetchDetail: async ({ commit }, id) => { }
}
// ✅ 正确:模块文件名小写,匹配业务名
// store/modules/marketing.js
// store/modules/order.js
3. 登出时重置 Store
// 在 user store 中
const actions = {
async resetToken({ commit }) {
commit('SET_TOKEN', '')
commit('SET_HAS_ROLES', false)
removeToken()
removeTenant()
}
}
// 登出时(permission.js 路由守卫中)
await store.dispatch('user/resetToken')
localStorage.clear()
locationHref() // 使用全局 locationHref 跳转(不用 router.push)
4. 分页数据格式
// 后端返回的分页数据格式
{
records: [], // 数据列表(非 rows)
total: 100,
current: 1,
size: 20
}
// 请求分页参数格式
{
page: { current: 1, size: 20 },
object: { ...queryParams } // 查询条件
}
参考文件
| Store | 路径 |
|---|---|
| Store 入口 | /Users/xujiajun/Developer/frontProj/web/src/store/index.js |
| 全局 Getters | /Users/xujiajun/Developer/frontProj/web/src/store/getters.js |
| 用户 Store | /Users/xujiajun/Developer/frontProj/web/src/store/modules/user.js |
| 权限 Store | /Users/xujiajun/Developer/frontProj/web/src/store/modules/permission.js |
| 应用 Store | /Users/xujiajun/Developer/frontProj/web/src/store/modules/app.js |
| 设置 Store | /Users/xujiajun/Developer/frontProj/web/src/store/modules/settings.js |
| 标签页 Store | /Users/xujiajun/Developer/frontProj/web/src/store/modules/tagsView.js |
注意事项
- 本项目使用 Vuex 3.x(非 Pinia),与 Vue 2 配套
- Store 模块必须设置
namespaced: true - 异步操作放在 Actions 中,同步操作放在 Mutations 中
- 分页数据用
records,不是rows(与 RuoYi 后端框架不同) - 登出使用
locationHref()而非router.push('/login'),目的是清除内存中的数据 adminMerchant为 true 时,用户是超级管理员(roleCode === 'ROLE_ADMIN'),可切换商户
Weekly Installs
2
Repository
xu-cell/ai-engi…ing-initGitHub Stars
8
First Seen
7 days ago
Security Audits
Installed on
amp2
cline2
opencode2
cursor2
kimi-cli2
codex2