vue2 - Day05 - VueX
Vuex 是 Vue.js 官方的状态管理库。它是一个让你能在应用中集中管理共享状态的工具。当应用的规模逐渐增大,组件之间的数据传递变得越来越复杂时,Vuex 就成为了救星,提供了一个集中式的存储来管理所有的组件状态,并且保证状态以一种可预测的方式发生变化。
文章目录
- 目的
- Vuex 怎么做的?
- (1). State
- <1> 为什么有 `data` 和 `state`?
- `data` 关心的是单个组件的内部状态;
- <2> 使用数据信息
- (2)Getters
- (3)Mutations
- Vuex 严格模式
- (4) Actions
- (5)Modules
- Vuex 的“心脏” —— 单向数据流
- 为什么 Vuex 很“牛”?
- 总结:Vuex 让你理清数据的“厨房”!
目的
Vuex 的目标是让你的 Vue 应用在状态管理上不至于像一锅乱炖,避免在多个组件间传递数据时乱七八糟。你可以想象,在 Vuex 中,所有状态都被“规范化”了,组件们可以优雅地共享这些数据,而不需要通过层层的父子传递 props 和事件。这也解决了“数据共享时,父组件、子组件、孙组件之间的数据流动混乱”的老大难问题。
- 集中式管理:把所有共享的状态存放在一个地方,统一管理,避免数据凌乱。
- 严格的单向数据流:让数据更新的过程清晰可控,不会出现“你修改我,我改你”的尴尬局面。
- 跨组件通信:组件之间不再需要通过复杂的 prop 和 event 来传递数据,只需要从 store 获取就好。
Vuex 怎么做的?
Vuex 采用了几个核心概念来实现这一切:State、Getters、Mutations、Actions 和 Modules。
(1). State
-
state
是存储数据的地方,它是 Vuex 的数据源。在应用中,组件需要共享的状态应该放在state
中。你可以将它看作 Vuex 提供的“全球变量”,它能够帮助你在组件间共享数据。 -
当然,如果你把所有东西都放进 state,那可能会导致一堆“杂货”,所以一定要有一定的规划,避免所有数据都成堆的乱象。 (´ω`)
const store = new Vuex.Store({
state: {
count: 0
}
})
<1> 为什么有 data
和 state
?
-
data
是用来管理组件自身的状态,关注的是单一组件内的数据变化; -
state
是 Vuex 用来管理全局状态的地方,目的是让多个组件能够共享和操作相同的数据。
换句话说:
特性 | data | state |
---|---|---|
作用范围 | 仅限于当前组件的局部状态 | 全局状态,多个组件共享 |
存储位置 | Vue 组件内部 | Vuex store(状态管理仓库) |
访问方式 | this.count | this.$store.state.count |
响应性 | 自动响应式更新视图 | 自动响应式更新视图 |
用途 | 处理单个组件的状态,通常是 UI 数据 | 处理跨组件共享的状态 |
举个例子,如果你有一个购物车应用,在每个商品详情页面,商品的数量和价格会保存在该组件的 data
中;而购物车总数、用户登录状态、支付信息等会保存在 Vuex 的 state
中,让不同组件都能访问和修改。
所以,data
和 state
是两个不同范围的状态管理工具,一个是组件级的局部状态管理,一个是全局级的状态管理。
<2> 使用数据信息
-
任何组件都可以通过
this.$store.state
来访问 Vuex 中的state
。// Vuex store const store = new Vuex.Store({ state: { count: 0 }, mutations: { increment(state) { state.count++; } } }); // 组件中访问 state export default { computed: { // 直接通过 this.$store.state 访问 state 中的数据 count() { return this.$store.state.count; } }, methods: { increment() { // 通过 mutation 更新 state this.$store.commit('increment'); } } }
-
通过辅助函数mapState访问
state
数据import { mapState } from 'vuex'; export default { computed: { // 使用 mapState 辅助函数 ...mapState({ count: state => state.count // 将 state.count 映射到组件的 computed 属性中 }) }, methods: { increment() { this.$store.commit('increment'); } } }
(2)Getters
getters
是从state
中派生出一些状态的“函数”,类似于 Vue 的计算属性,它们不会直接改变state
,而是返回一些加工过的计算结果。- 例如,如果
state
中有一个列表,我们可以在getters
中处理这些数据,像是过滤出有效的元素或者计算某个值。
const store = new Vuex.Store({
state: {
count: 0
},
getters: {
doubleCount: state => state.count * 2
}
})
Getters 可不只是“取拿冰箱里的食材”,还会根据你的需求“做点小加工”,像做饭前的切菜一样(如果你能忍受长时间等待的切菜过程…)。
(3)Mutations
Mutations
就是唯一合法的修改state
的唯一途径!它们是同步的,你不能在这里做异步操作(想抄捷径?做梦去吧)。每次要改变 state 的内容,你都必须通过 mutation 来“正式授权”进行修改。
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment(state) {
state.count++
}
}
})
Mutations 就像一个“厨房的管理员”,它是唯一能决定“今天菜单”是什么的,不通过它你就不能随便动手。想做什么就要跟它打招呼!
-
例如,你可能会写一个 mutation 来修改用户的登录状态:
mutations: { login(state) { state.loggedIn = true; } }
Vuex 严格模式
要启用 Vuex 的严格模式,只需要在创建 Vuex.Store
实例时,将 strict
属性设置为 true
即可。
const store = new Vuex.Store({
strict: true, // 启用严格模式
});
- 允许通过
mutations
修改state
:如果你按照 Vuex 的规范通过commit
调用mutations
来修改state
,Vuex 严格模式不会报错。 - 不允许直接修改
state
:如果你在 Vue 组件或其他地方直接修改state
,严格模式会报错,并且提供警告。比如:
this.$store.state.count++; // 这是不被允许的,严格模式下会触发警告
Vuex 在开发环境下会检测到这种不合规的操作,并提示错误信息。
(4) Actions
-
actions
类似于mutations
,但它们可以包含异步操作。actions
用来派发 mutation,通常你会在actions
中执行一些异步操作(比如向后端发送请求),然后通过commit
来触发 mutation。actions: { async fetchData({ commit }) { const data = await axios.get('/api/data'); commit('setData', data); } }
-
它们可以像一个小助手一样,帮你完成一些复杂的异步任务(比如 API 请求),最后将结果交给 mutation 来更新状态。
const store = new Vuex.Store({
state: {
count: 0
},
actions: {
incrementAsync({ commit }) {
setTimeout(() => {
commit('increment')
}, 1000)
}
}
})
它们可以像一个小助手一样,帮你完成一些复杂的异步任务(比如 API 请求),最后将结果交给 mutation 来更新状态。
(5)Modules
- Vuex 还支持将 store 分成多个模块,每个模块都有自己的 state、mutations、actions 和 getters。这对于大型应用来说非常有用,它能帮助你将不同的业务逻辑进行分离。
- 例如,如果你有一个用户模块和一个商品模块,你可以将它们分别定义在不同的模块中,避免了一个大的
store
变得过于复杂。 - 看起来很像分区管理,有了这个功能,你就可以把代码管理得像一个井然有序的图书馆,而不是一团乱麻(¬_¬)。
const store = new Vuex.Store({
modules: {
moduleA: {
state: { count: 0 },
mutations: {
increment(state) {
state.count++
}
}
}
}
})
Modules 就是让你可以分摊厨房的责任,让多个厨师各司其职,避免一锅煮成了乱炖(不同模块管理自己的状态,既不冲突又井然有序)。
Vuex 的“心脏” —— 单向数据流
Vuex 强调了单向数据流(state -> getter -> component -> actions -> mutation -> state),你可以把它看作是一个规范化的流水线,每一步都非常清晰:
- state 提供数据;
- getter 提供处理过的数据;
- component 用来展示数据;
- actions 负责异步操作;
- mutation 最终改变数据。
整个流程都遵循着严格的规则,数据像流水一样流动。想要逆流而上?想都别想(除非是调皮的 mutation…)。
为什么 Vuex 很“牛”?
Vuex 是一个非常严谨的库,它的设计理念非常高大上(可能是你不想用它时最喜欢说的句子)。它让你避免了在组件间“乱搞”数据的尴尬局面,确保了每个数据变动都有清晰的路径和轨迹。
Vuex 的优点包括:
- 集中管理状态:所有的状态都集中在 store,方便管理。
- 严格的数据流控制:单向数据流让数据变化有迹可循。
- 便捷的调试工具:Vuex 提供的时间旅行调试功能让你随时了解数据如何变化。
- 模块化管理:即使是庞大的应用,也能清晰拆分和管理。
但如果你是小型应用,Vuex 的使用就有点像“用大炮打蚊子”。你可能会觉得:这怎么像是拿高科技武器去捉小猫咪呢?(不过一旦应用扩展,你会发现 Vuex 的威力)。
总结:Vuex 让你理清数据的“厨房”!
Vuex 是一个强大的工具,它让 Vue 应用的状态管理变得更加清晰和可预测。在大型应用中,Vuex 能够有效地集中管理状态,避免了直接操作 DOM 元素的凌乱(毕竟,Vuex 和 DOM 元素并没有什么关系哦~(。•́︿•̀。))。
当然,如果你是开发一个小型应用,Vuex 可能就有点“重”。不过没关系,就像你不需要开动整个火车来送一包米那样,小应用用别的状态管理方法就够了。所以,Vuex 不适合“短跑”,但适合长期合作!(如果你不怕它有时“拗口”…)