vuex
1、vuex 是什么?
“Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。”
既然是状态管理,那么可简单理解成状态 和 管理两个部分。
状态其实就是一个表示组件当前数据的对象。
而管理就是通过定义一些方法去改变状态。
2、vuex类似于全局对象,但又有不同。
首先,vuex是响应式的,也就是说state改变视图也会跟着改变。
其次,不能直接改变state,只能通过commit(提交)mutation才能改变。
3、如果是使用模块的写法,必须在使用vuex时调用vue.use(vuex)
4、核心概念
State
Getter
Mutation
Action
Module
5、State
“单一状态树” : 每个应用将仅仅包含一个 store 实例。
如何在组件中展示状态呢?
(1)最简单的方式: 是在计算属性中返回某个状态。
computed: {
count () {
return store.state.count
}
}
(2)调用Vue.use(Vuex),将状态从根组件注入到每一个子组件之中。
然后在根组件的配置对象中加入store对象。
子组件通过 this.$store.state 访问状态。
mapState 辅助函数
帮助我们同时生成多个计算属性。
mapState([' name '])
使用对像展开运算符
...mapState([' name '])
6、Getter
Vuex 允许我们在 store 中定义“getter”(可以认为是 store 的计算属性)。
getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
Getter 接受 state 作为其第一个参数:
Getter 也可以接受其他 getter 作为第二个参数:
你也可以通过返回一个函数来传参。
使用getter:
this.$store.getters
mapGetters
辅助函数
mapGetters
辅助函数仅仅是将 store 中的 getter 映射到局部计算属性:
computed: {
// 使用对象展开运算符将 getter 混入 computed 对象中
...mapGetters([ 'doneTodosCount', 'anotherGetter' ])
}
如果你想将一个 getter 属性另取一个名字,使用对象形式:
mapGetters({
// 映射 `this.doneCount` 为 `store.getters.doneTodosCount`
doneCount: 'doneTodosCount'
})
7、Mutation
更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。
mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。
触发指定的事件改变指定的数据。
回调函数的第一个参数是: state对象。
第二个参数可以是你想要设置新的值。
触发事件: store.commit('increment')
注意:
mutation 必须是同步函数。
在组件中触发事件:
this.$store.commit('xxx')
或者使用辅助函数: ...mapMutations()
8、Action
其实就是异步操作来调用commit()
mutations:{
setCount:function(state, v){
state.count = v
}
}
对应的Action是:
actions: {
setCount:function(context){
context.commit('setCount')
}
}
context对象是与 store 实例具有相同方法和属性的对象,但不是store对象。
那要怎样来触发action呢???
store.dispatch("setCount");
这样就可以异步的改变状态了,本质上就是在action内部异步的执行mutation。
与mutation一样的是,action也可以通过第二个参数来传递要设置的新值。
在组件中怎么触发action???
this.$store.dispatch('xxx')
或者使用 mapActions()
如果想要在异步的action结束后进行操作,可以和Promise配合使用。
9、Module
由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。
当应用变得非常复杂时,store 对象就有可能变得相当臃肿。
Vuex 允许我们将 store 分割成模块(module)。
每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:
每个模块的状态的定义方式跟上面讲的一样。
唯一不同的是怎么讲子模块的状态加入到整个状态中去。
可以通过给主状态添加modules属性:
modules:{
moduleA : storeA
//...
}
那如果要在使用moduleA模块上的状态时,与平常的方式有所不同。
使用state
store.state.moduleA
使用mutation
第一个参数是局部的模块state
使用action
第一个参数也是context
局部状态是context.state
根节点状态是context.rootState
使用getter
对于模块内部的 getter,根节点状态会作为第三个参数暴露出来:
getters: {
sumWithRootCount (state, getters, rootState) {
return state.count + rootState.count
}
}