事出必有因,第一次自己这么认真的去构思去写博客,随着项目的需求,组件之间的数据交互变得越来越频繁且关系密切,如果这个时候还局限于props和$emit,觉得自己太low了,于是乎,就想要好好的学习一下vuex,之后发现自己用错了它的功能,接下来好好说道说道。
介绍
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。(我自己感觉其实就是个管家…)
安装
NPM
npm install vuex –save
Yarn
yarn add vuex
在vue项目中引用一些公用的库等都写在main.js,但此次不直接写在其中,通过引入写在store.js文件中,main.js中引入store.js(以下代码均为store.js中内容):
1 | // main.js |
1 | // store.js |
成员介绍
State
状态库: Vuex使用的是单一状态树,也就是一个应用仅一个store实例。这个状态库中的数据,在项目任何组件中都可以使用,是全局的状态。1
2
3const state = {
numList: [0, 1, 2, 3, 4, 5]
}
Getter
获取状态数据:类似于computed计算属性,这个部分通常写一些处理状态数据的代码,比如过滤state中的某个状态数据。
第一个参数是state,因为getter会暴露在store中,所以第二个参数getters是可以接受其他模块中的getter
1 | const getters = { |
Mutation
变化:类似于组件中methods,在vuex中改变store中state的值,只能通过mutation,注意mutation只进行同步操作。
1 | const mutations = { |
mutation还可以接受传值,这样代码可以改写为:1
2
3
4
5const mutations = {
increment (state, value = 1) {
state.numList.forEach(num => { num += value })
}
}
触发mutation比较特殊,是通过commit:
1 | store.commit('increment', 2) |
使用mutation改变状态有需要遵守的规则这里提一个,剩下可以查看官方文档说明。
mutation接受的参数过多时,通常使用对象来作为参数接受,平常封装函数我们也经常这么干,所以so easy,mutation改变状态时最好是用新对象来代替旧对象(ES6写法)
1 | state.obj = { ...state.obj, newProp: 123 } |
Action
Action 类似于 mutation,不同在于:
- Action 提交的是 mutation,而不是直接变更状态。
- Action 可以包含任意异步操作。
Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,所以可以使用context.commit, context.rootState, context.getters。
1 | const actions = { |
action可以结合ES2015中promise使用:
1 | const actions = { |
触发action是通过dispatch:
1 | store.dispatch('increment') |
mutation和action都可以通过对象风格的方式提交和分发:
1 | commit({ |
Module
module主要针对于比较大型的项目,数据比较繁琐都写在一起会不容易维护,可以根据功能等将store模块化,每个模块拥有自己的 state、mutation、action、getter。我们上面的代码就可以将名称store.js换位num.js仅仅作为操作数据的模块。
1 | const moduleA = { |
vue文件中使用方法
state,getter,mutation,action在vue文件中使用方式均有两种,这里拿state作为例子,其他类似,聪明的你肯定会举一反三:
- 通过mapState
1 | import { mapState } from 'vuex' |
如果名字一致,也可以写在数组当中:1
2
3mapState([
'numList'
])
此文件中后续使用this.numList或者this.numArr
- 通过$store
1
this.$store.state.numList
如果是模块化的store,请看官方说明
项目结构
1 | ├── index.html |