什么是Vuex?
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。(我理解为就是一个管理全局状态的一个仓库)
什么时候使用Vuex?
Vuex 可以帮助我们管理共享状态,并附带了更多的概念和框架。如果我们开发的是一个简单的单页应用项目,可能不需要使用 Vuex。但是,当我们需要处理复杂的组件通信、跨组件的数据共享、组件状态的复用、统一状态管理等功能时,就需要使用像 Vuex 或 Pinia 这样的状态管理库来帮助我们管理项目中的状态。
如何使用Vuex?
首先还是安装库
npm install vuex@next --save
这个后面添加个--save会将我们安装的包添加到package.json 文件的 dependencies 部分。这意味着如果我们的项目被别人克隆并且运行npm install 时,npm 会自动安装 package.json 中列出的所有依赖。但在npm 5.0.0 及其之后版本中,--save 选项已经是默认行为,所以我们也可以不用添加。
搭建store
每一个 Vuex 应用的核心就是 store(仓库)。“store”基本上就是一个容器,它包含着你的应用中大部分的状态 (state) 。Vuex 和单纯的全局对象有以下两点不同:
- Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
- 你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。
// src/store/index.js
import { createStore } from 'vuex';
const store = createStore({
// 定义应用程序的全局状态
state: {
count: 0,
user: null
},
// 同步变更状态
mutations: {
increment(state) {
state.count++;
},
decrement(state) {
state.count--;
},
setUser(state, user) {
state.user = user;
}
},
// 异步操作,可以在这里进行异步请求,然后提交 mutations 改变状态
actions: {
increment({ commit }) {
commit('increment');
},
decrement({ commit }) {
commit('decrement');
},
fetchUser({ commit }) {
// 模拟异步请求
setTimeout(() => {
const user = { name: 'John Doe', age: 30 };
commit('setUser', user);
}, 1000);
}
},
// 派生状态,用于计算基于状态的值
getters: {
doubleCount(state) {
return state.count * 2;
},
isLoggedIn(state) {
return !!state.user;
}
}
});
export default store;
五个核心概念
State、 Getter、Mutation 、Action、 Module
- state => 基本数据(数据源存放地)
- getters => 从基本数据派生出来的数据
- mutations => 提交更改数据的方法,同步
- actions => 像一个装饰器,包裹mutations,使之可以异步。
- modules => 模块化Vuex
state
State 是 Vuex 存储的单一源。你可以在 store 中定义应用程序的所有状态,然后在组件中访问和使用这些状态。上面 store 我们就定义了两个状态 count 和 user。
getters
Getters 类似于组件的计算属性(computed properties)。它们用于派生一些状态或进行一些状态的计算,返回新的结果。Getters 接受 state 作为其第一个参数。
const store = createStore({
state: {
count: 0
},
getters: {
doubleCount(state) {
return state.count * 2;
}
}
});
在组件中使用 getters:
computed: {
doubleCount() {
return this.$store.getters.doubleCount;
}
}
mutations
Mutations 是唯一能够修改 Vuex state 的方法。每个 mutation 都有一个类型 (type) 和一个回调函数 (handler)。回调函数接收 state 作为第一个参数,可以直接改变 state。mutations 必须是同步函数。
const store = createStore({
state: {
count: 0
},
mutations: {
increment(state) {
state.count++;
},
decrement(state) {
state.count--;
}
}
});
在组件中提交 mutation:
methods: {
increment() {
this.$store.commit('increment');
},
decrement() {
this.$store.commit('decrement');
}
}
actions
Actions 类似于 mutations,不同在于:
- Action 提交的是 mutation,而不是直接变更状态。
- Action 可以包含任意异步操作。
const store = createStore({
state: {
count: 0
},
mutations: {
increment(state) {
state.count++;
}
},
actions: {
incrementAsync({ commit }) {
setTimeout(() => {
commit('increment');
}, 1000);
}
}
});
在组件中分发 action:
methods: {
incrementAsync() {
this.$store.dispatch('incrementAsync');
}
}
modules
在大型应用中,单一的 state 对象会变得臃肿。Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutations、actions 和 getters,甚至可以嵌套子模块。
const moduleA = {
state: () => ({ count: 0 }),
mutations: {
increment(state) {
state.count++;
}
},
actions: {
increment({ commit }) {
commit('increment');
}
},
getters: {
doubleCount(state) {
return state.count * 2;
}
}
};
const store = createStore({
modules: {
a: moduleA
}
});
在组件中访问模块状态:
computed: {
count() {
return this.$store.state.a.count;
},
doubleCount() {
return this.$store.getters['a/doubleCount'];
}
}
总结
在选择状态管理库时,Vuex 和 Pinia 是两个常见的选项。而对于我来说,我觉得 Pinia 更值得优先选择。对比下来,Pinia 比 Vuex 更简洁,在学习难度上 Pinia 也相对简单一些。Pinia 提供了更直观和现代的 API,更符合 Vue 3 的组合式 API 设计理念。它的开发体验更加愉快,支持热重载和插件系统,并与 Vue Devtools 完美集成。虽然 Vuex 有着广泛的社区支持和成熟的生态系统,但 Pinia 的快速增长和 Vue 核心团队的支持使其成为新的官方推荐状态管理库。因此,对于新的项目或者希望采用更现代化状态管理方式的项目,Pinia 是一个更好的选择。想简单了解一下Pinia可以来到我这篇文章简单了解一下你知道的状态管理库Pinia