Vuex

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式

Vuex 使用过程演示

vue-cli3新创建出来的项目为例,演示 Vuex 的使用过程。

创建项目:

1
2
3
vue create vuex-test
cd vuex-test
npm run serve

安装vuex:

1
npm i vuex -S

进入项目的src/下新建一个文件store/index.js,并写入:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// store/index.js
import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

const store = new Vuex.Store({
// 容器 (构造函数Store开头大写)
state: {
// 状态
count: 0,
},
mutations: {
// 变化(使用mutations提交改变是为了方便追踪变化记录)
increment(state) {
state.count++;
},
},
});
export default store; // 导出

进入main.js 注入store使所有vue组件能够使用vuex :

1
2
3
4
5
6
7
8
9
10
11
12
13
// main.js
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";

Vue.config.productionTip = false;

new Vue({
router,
store,
render: (h) => h(App),
}).$mount("#app");

现在我们可以从组件的方法提交一个变更:

1
2
3
4
5
6
methods: {
increment() {
this.$store.commit('increment') // .commit('<mutations里的事件名>')
console.log(this.$store.state.count)
}
}

在组件模板中使用状态:

1
2
3
{{ count }}

computed: { count() { return this.$store.state.count } }

state 状态的改变会触发 computed 的重新计算

核心概念

State

Vuex 使用单一状态树,每个应用将仅仅包含一个 store 实例

mapState 辅助函数

当一个组件需要获取多个状态的时候,将这些状态都声明为计算属性会有些重复和冗余。为了解决这个问题,我们可以使用 mapState 辅助函数帮助我们生成计算属性,让你少按几次键:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 在单独构建的版本中辅助函数为 Vuex.mapState
import { mapState } from "vuex";

export default {
// ...
computed: mapState({
// 箭头函数可使代码更简练
count: (state) => state.count,

// 传字符串参数 'count' 等同于 `state => state.count`
countAlias: "count",

// 为了能够使用 `this` 获取局部状态,必须使用常规函数
countPlusLocalState(state) {
return state.count + this.localCount;
},
}),
};

上面 mapState()参数内三个方式都是获取 count 的值

当映射的计算属性的名称与 state 的子节点名称相同时,我们也可以给 mapState 传一个字符串数组。

1
2
3
4
computed: mapState([
// 映射 this.count 为 store.state.count
"count",
]);

对象展开运算符

mapState 函数返回的是一个对象。可使用对象展开运算符将此对象混入到外部对象中

1
2
3
4
5
6
7
computed: {
localComputed () { /* ... */ }, // 其他的计算属性
// 使用对象展开运算符将此对象混入到外部对象中
...mapState({
// ... 这里面和上面的获取方式是一样的
})
}

组件仍然保有局部状态

使用 Vuex 并不意味着你需要将所有的状态放入 Vuex。虽然将所有的状态放到 Vuex 会使状态变化更显式和易调试,但也会使代码变得冗长和不直观。如果有些状态严格属于单个组件,最好还是作为组件的局部状态。你应该根据你的应用开发需要进行权衡和确定。