getters
类似于单个组件中的计算属性
默认参数为state,参数可以添加getters,但是不能添加其他
在store中定义getters
getters:{
powerCounter(state){
return state.count*state.count;
}
},
使用时:
<h2>{{$store.getters.powerCounter}}</h2>
state:{
count:1000,
students:[
{
id:1,
age:14,
},
{
id:2,
age:16,
},
{
id:3,
age:18,
},
]
},
在getters中可以选择年龄大于age的student,由于getters不能为age,所以只能返回一个函数进行调用返回函数添加age参数完成要求。
moreAge(state){
return function (age) {
return state.students.fill(s=>s.age>age)
}
}
使用时$store.getters.moreAge(12)来调用
mutations
Vuex的store状态的更新唯一方式:提交mutation
mutation主要包括两个部分:字符串的时间类型type,一个回调函数(第一个参数为state)
定义与更新方式
mutation定义方式如下:
mutations:{
increment(state){
state.count++
},
},
mutation更新如下:
add(){
this.$store.commit('increment')
}
参数问题
如果mutation想传入其他参数
incrementCount(state,count){
state.count-=count
}
this.$store.commit('incrementCount',count)
提交风格
也可以使用以下来传递参数
但是这样传递的参数为一个对象
addCount(count){
this.$store.commit({
type:'incrementCount',
count:count//ES6语法可以简写成count
})
}
传递一个对象参数,所以payload为一个对象
incrementCount(state,payload){
state.count-=payload.count
}
mutation响应规则
Vuex的store中的state是响应式的,当state中数据改变时,Vue组件自动更新
这需要遵循Vuex对应的规则:一开始都定义在state中,这些属性都会被加入响应式系统中,而响应式系统会监听属性的变化,当属性变化时,界面就会刷新。
如果之后添加例如:
state.student[name]='123’添加新的属性,界面不会进行刷新,但是确实添加了name属性。
如果确实需要刷新,实现方法:
Vue.set(state.student, ‘name’, ‘123’)添加了响应式
如果需要删除某个属性:
delete state.student.age也不是响应式
Vue.delete(state.student, ‘age’)是响应式的
mutation常量类型
mutation中的type与调用时方法一致,可以定义常量来使用避免报错
在store下建立一个文件夹,定义一些type常量
export const InCREMENT = 'increment'
在store中使用
import * as types from './mutation-types'
mutations:{
[types.InCREMENT](state){
state.count++
}
}
在组件中使用
import * as types from "./store/mutation-types"
add(){
this.$store.commit(types.InCREMENT)
},
mutation同步函数
Vuex要求我们Mutation中的方法必须是同步方法:
因为使用devtools时,可以帮助我们捕捉mutation的快照,但是如果时异步,那么devtools将不能很好的追踪这个操作什么时候完成。
如下异步操作:
decrement(state){
setTimeout(function () {
state.count--
}, 1000)
},
数据显示修改正确,但是devtools显示信息错误
所以mutation必须是同步操作。
action
如果必须使用异步操作时,可以使用action来调用mutation
mutation中不变为同步
decrement(state){
}
actions中添加异步操作
actions:{
//默认参数为context上下文,可以理解成store对象
acDecrement(context,payload){
setTimeout(function () {
context.commit('decrement',payload)
},1000)
}
},
组件中使用,调用action时需要使用dispatch,也可以添加参数,直接在type后面添加
this.$store.dispatch("acDecrement",‘123’)
module
Vuex使用单一状态树,但是由于state的状态过多,可以将七进行模块化来处理:
modules:{
a:{
state:{},
mutations:{},
actions:{},
getters:{},
},
b:{
state:{},
mutations:{},
actions:{},
getters:{},
}
}
继续进行抽离:
const moduleA = {
state:{
name:'123A',
},
}
const moduleB = {
state:{
name:'123B',
},
}
//创建对象
const store = new Vuex.Store({
modules:{
a:moduleA,
b:moduleB,
}
})
使用时,$store.state.a.name,注意state和a的顺序s
$store.commit(‘fn’),先在store下的mutations寻找,然后在a,b模块的mutation中寻找
$store.getters(‘fn’),先在store下的getters寻找,然后在模块中寻找
如果需要在getters中调用自身的getters,参数添加getters,gettters.名字可以调用
actions如何实现:同样是参数为context,而context.commit只调用自身的mutations,而不会调用root的mutation
如果模块中想引用Store下的state,则使用rootState,表示根下的State