state:
state即Vuex中的基本数据!
state就是用来存放数据,若是对数据进行处理输出,比如数据要过滤,一般我们可以写到computed中。但是如果很多组件都使用这个过滤后的数据,这就是getters存在的意义。我们可以认为,【getters】是store的计算属性。
getters(相当于State的计算属性) :
1基础用法:
main.js:
const store = new Vuex.Store({
state: {
list: [1, 3, 5, 7, 9, 20, 30]
},
getters: {
filteredList: state => {
return state.list.filter(item => item > 5)
}
}
})
index.vue:
<script>
export default {
name: "index.vue",
computed: {
list() {
return this.$store.getters.filteredList;
}
}
}
</script>
2.内部依赖
getter 可以依赖其它已经定义好的 getter。比如我们需要统计过滤后的列表数量,就可以依赖之前定义好的过滤函数。
main.js:
const store = new Vuex.Store({
state: {
list: [1, 3, 5, 7, 9, 20, 30]
},
getters: {
filteredList: state => {
return state.list.filter(item => item > 5)
},
listCount: (state, getters) => {
return getters.filteredList.length;
}
}
})
index.vue:
<template>
<div>
过滤后的列表:{{list}}
<br>
列表长度:{{listCount}}
</div>
</template>
<script>
export default {
name: "index.vue",
computed: {
list() {
return this.$store.getters.filteredList;
},
listCount() {
return this.$store.getters.listCount;
}
}
}
</script>
mutation(提交更改数据的方法,同步!必须是同步函数) :
使用vuex修改state时,有两种方式:
1)可以直接使用 this.$store.state.变量 = xxx;
2)this.$store.dispatch(actionType, payload)或者 this.$store.commit(commitType, payload)
main.js:
const store = new Vuex.Store({
strict: true, // strict: true, 若开启严格模式只要不经过 mutation的函数,则会报错
state: {
cartNum: 0, // 购物车数量
},
mutations: {
// 加1
INCREMENT(state) {
state.cartNum++;
},
}
})
index.vue:
import baseStore from '../../../main.js';
methods: {
addCarts () {
baseStore.commit('INCREMENT')
},
}
异同点:
1)共同点: 能够修改state里的变量,并且是响应式的(能触发视图更新)
2)不同点:
若将vue创建 store 的时候传入 strict: true, 开启严格模式,那么任何修改state的操作,只要不经过
mutation的函数,
vue就会 throw error : [vuex] Do not mutate vuex store state outside mutation handlers。
action(像一个装饰器,包裹mutations,使之可以异步。) :
action的功能和mutation是类似的,都是去变更store里的state,不过action和mutation有两点不同:
1)action主要处理的是异步的操作,mutation必须同步执行,而action就不受这样的限制,也就是说action中我们既可以处理同步,也可以处理异步的操作
2)action改变状态,最后是通过提交mutation
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
increment (context) {
setInterval(function(){
context.commit('increment')
}, 1000)
}
}
})
注意:Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用 context.commit 提交一个 mutation,或者通过 context.state 和 context.getters 来获取 state 和 getters。
分发actions
Action 通过 store.dispatch 方法触发:
store.dispatch('increment')
modules ( 模块化Vuex):
背景:在Vue中State使用是单一状态树结构,应该的所有的状态都放在state里面,如果项目比较复杂,那state是一个很大的对象,store对象也将对变得非常大,难于管理。
module:可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理
const moduleA = {
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: { ... },
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态