✨ Vuex 状态管理最佳实践指南
This commit is contained in:
parent
5546635e31
commit
eb49928833
|
@ -1,12 +1,13 @@
|
|||
import Vue from "vue";
|
||||
import Vuex from "vuex";
|
||||
import count from "./modules/count";
|
||||
Vue.use(Vuex);
|
||||
|
||||
const store = new Vuex.Store({
|
||||
state: {},
|
||||
mutations: {},
|
||||
actions: {},
|
||||
modules: {},
|
||||
modules: { count },
|
||||
});
|
||||
|
||||
export default store;
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
import Vue from "vue";
|
||||
import Vuex from "vuex";
|
||||
Vue.use(Vuex);
|
||||
|
||||
const count = {
|
||||
namespaced: true,
|
||||
state: { num: 1, sum: 0 },
|
||||
actions: {
|
||||
// 奇数相加
|
||||
incrementOdd(context) {
|
||||
// 可以从上下文中获取sum
|
||||
if (context.state.sum % 2) {
|
||||
context.commit("INCREMENT_ODD");
|
||||
}
|
||||
},
|
||||
incrementWait(context) {
|
||||
setTimeout(() => {
|
||||
context.commit("INCREMENT_WAIT");
|
||||
}, 500);
|
||||
},
|
||||
},
|
||||
mutations: {
|
||||
// 相加
|
||||
INCREMENT(state) {
|
||||
state.sum += state.num;
|
||||
},
|
||||
// 相减
|
||||
DECREMENT(state) {
|
||||
state.sum -= state.num;
|
||||
},
|
||||
// 奇数相加
|
||||
INCREMENT_ODD(state) {
|
||||
state.sum += state.num;
|
||||
},
|
||||
INCREMENT_WAIT(state) {
|
||||
state.sum += state.num;
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default count;
|
|
@ -0,0 +1,178 @@
|
|||
# Vuex 状态管理最佳实践指南
|
||||
|
||||
## 一、核心架构解析
|
||||
|
||||
### 1. 模块化结构
|
||||
```javascript
|
||||
// store/index.js - 主入口文件
|
||||
import count from './modules/count'
|
||||
|
||||
export default new Vuex.Store({
|
||||
modules: {
|
||||
count // 启用命名空间的计数模块
|
||||
}
|
||||
})
|
||||
|
||||
// store/modules/count.js - 计数模块
|
||||
export default {
|
||||
namespaced: true, // 启用命名空间
|
||||
state: {
|
||||
num: 1,
|
||||
sum: 0
|
||||
},
|
||||
mutations: { /* 同步操作 */ },
|
||||
actions: { /* 异步操作 */ }
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 数据流示意图
|
||||
```
|
||||
组件 → dispatch → Actions → commit → Mutations → mutate → State → 响应式更新 → 组件
|
||||
```
|
||||
|
||||
## 二、代码优化建议
|
||||
|
||||
### 1. 组件中的优化
|
||||
```javascript
|
||||
// 使用map辅助函数简化代码
|
||||
import { mapActions, mapMutations, mapState } from 'vuex'
|
||||
|
||||
export default {
|
||||
computed: {
|
||||
...mapState('count', ['sum', 'num'])
|
||||
},
|
||||
methods: {
|
||||
...mapMutations('count', ['INCREMENT', 'DECREMENT']),
|
||||
...mapActions('count', ['incrementOdd', 'incrementWait'])
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Store 中的优化
|
||||
```javascript
|
||||
// 使用常量替代字符串 mutation 类型
|
||||
const types = {
|
||||
INCREMENT: 'INCREMENT',
|
||||
DECREMENT: 'DECREMENT'
|
||||
}
|
||||
|
||||
const count = {
|
||||
mutations: {
|
||||
[types.INCREMENT](state) {
|
||||
state.sum += state.num
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 三、最佳实践规范
|
||||
|
||||
### 1. 命名规范
|
||||
| 类型 | 命名风格 | 示例 |
|
||||
| -------- | ------------ | ----------------- |
|
||||
| Mutation | 大写+下划线 | `INCREMENT` |
|
||||
| Action | camelCase | `fetchData` |
|
||||
| Getter | 形容词/名词 | `filteredList` |
|
||||
| Module | 业务相关名词 | `user`, `product` |
|
||||
|
||||
### 2. 操作分离原则
|
||||
- **Mutations**:
|
||||
- 只做简单状态赋值
|
||||
- 必须是同步函数
|
||||
- 命名类似事件(`SET_USER_INFO`)
|
||||
|
||||
- **Actions**:
|
||||
- 处理业务逻辑
|
||||
- 可以包含异步操作
|
||||
- 命名类似方法(`fetchUserData`)
|
||||
|
||||
### 3. 模块化建议
|
||||
1. 按功能/业务划分模块
|
||||
2. 每个模块启用命名空间
|
||||
3. 模块内维护独立state
|
||||
|
||||
## 四、高级应用场景
|
||||
|
||||
### 1. 动态模块注册
|
||||
```javascript
|
||||
// 在需要时加载模块
|
||||
store.registerModule('dynamicModule', {
|
||||
// 模块定义
|
||||
})
|
||||
```
|
||||
|
||||
### 2. 表单处理方案
|
||||
```javascript
|
||||
// 使用双向绑定计算属性
|
||||
computed: {
|
||||
num: {
|
||||
get() { return this.$store.state.count.num },
|
||||
set(value) { this.$store.commit('count/UPDATE_NUM', value) }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 插件开发
|
||||
```javascript
|
||||
// 持久化插件示例
|
||||
const persistPlugin = store => {
|
||||
store.subscribe((mutation, state) => {
|
||||
localStorage.setItem('vuex_state', JSON.stringify(state))
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
## 五、性能优化技巧
|
||||
|
||||
### 1. 大型状态树
|
||||
- 使用模块懒加载
|
||||
- 避免在state中存储大对象
|
||||
|
||||
### 2. 计算属性缓存
|
||||
```javascript
|
||||
getters: {
|
||||
bigSum: state => {
|
||||
// 复杂计算会被缓存
|
||||
return heavyCalculation(state.sum)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 批量更新
|
||||
```javascript
|
||||
// 合并多个mutation
|
||||
actions: {
|
||||
bulkUpdate({ commit }, payload) {
|
||||
commit('UPDATE_A', payload.a)
|
||||
commit('UPDATE_B', payload.b)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 六、常见问题解决方案
|
||||
|
||||
1. **热重载问题**:
|
||||
```javascript
|
||||
if (module.hot) {
|
||||
module.hot.accept(['./modules/count'], () => {
|
||||
store.hotUpdate({ modules: { count } })
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
2. **循环依赖**:
|
||||
- 避免模块间互相引用
|
||||
- 使用全局事件总线处理跨模块通信
|
||||
|
||||
3. **调试技巧**:
|
||||
- 使用Vue Devtools追踪状态变化
|
||||
- 添加logger插件记录mutation
|
||||
|
||||
## 七、与Vue3的Pinia对比
|
||||
|
||||
| 特性 | Vuex | Pinia |
|
||||
| ---------- | ------------ | -------- |
|
||||
| 语法 | 较复杂 | 更简洁 |
|
||||
| 模块化 | 需要配置 | 自动支持 |
|
||||
| TypeScript | 需要额外配置 | 完美支持 |
|
||||
| 体积 | 较大 | 更轻量 |
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div>
|
||||
<h1>当前求和为:{{ sum }}</h1>
|
||||
<select v-model.number="num">
|
||||
<h1>当前求和为:{{ $store.state.count.sum }}</h1>
|
||||
<select v-model.number="$store.state.count.num">
|
||||
<option :value="1">1</option>
|
||||
<option :value="2">2</option>
|
||||
<option :value="3">3</option>
|
||||
|
@ -18,27 +18,20 @@
|
|||
export default {
|
||||
name: "CountInfo",
|
||||
data() {
|
||||
return {
|
||||
num: 1,
|
||||
sum: 0,
|
||||
};
|
||||
return {};
|
||||
},
|
||||
methods: {
|
||||
increment() {
|
||||
this.sum += this.num;
|
||||
this.$store.commit("count/INCREMENT");
|
||||
},
|
||||
decrement() {
|
||||
this.sum -= this.num;
|
||||
this.$store.commit("count/DECREMENT");
|
||||
},
|
||||
incrementOdd() {
|
||||
if (this.sum % 2) {
|
||||
this.sum += this.num;
|
||||
}
|
||||
this.$store.dispatch("count/incrementOdd");
|
||||
},
|
||||
incrementWait() {
|
||||
setTimeout(() => {
|
||||
this.sum += this.num;
|
||||
}, 500);
|
||||
this.$store.dispatch("count/incrementWait");
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue