1.getters可以视为计算属性,当数据需要变化后再传给其他组件时,可以使用getters,默认传入state参数
getters:{
powerCounter(state){
return state.counter * state.counter
},
more20stu(state){
return state.students.filter(s => s.age > 20)
}
}
在调用时,使用$store.getters.方法名
,如$store.getters.powerCounter
即可
2.getters传递参数
getters里面除了返回固定的值,还可以返回函数
getters中的某个函数如果想接收参数,需要用返回函数的方法
getters:{
powerCounter(state){
return state.counter * state.counter
},
more20stu(state){
return state.students.filter(s => s.age > 20)
},
more20stuLength(state,getters){
return getters.more20stu.length
},
moreAgeStu(state){
// 返回函数
return function(age) {
return state.student.filter(s => s.age > age)
}
}
}
vuex的store状态的唯一更新方式:提交mutation
mutation主要包括两部分:
mutation传递参数
在通过mutation更新数据时,有可能我们希望携带一些额外的参数
参数被称为是mutation的载荷(payload)
组件中的代码
methods:{
addCount(count){
// 传递单个参数
this.$store.commit('incrementCount',count)
},
addStudent(){
// 传递多个参数
const stu = {
id:114,name:'alan'}
this.$store.commit('addStudent',stu)
}
}
mutation内的代码
mutation:{
incrementCount(state,count){
state.counter += count
},
addStudent(state,stu){
state.students.push(stu)
}
}
mutation的两种提交风格
this.$store.commit('increment',count)
,这种情况下count的类型为一个变量this.$store.commit({
type:'increment',
count
})
所以在mutation中,当利用特殊形式提交封装时,用payload载荷来接收
mutation:{
incrementCount(state,payload){
// payload载荷
state.count += payload.count
}
}
一开始就被定义在store对象内部的state中的属性都会被加入到响应式系统中,而响应式系统会监听属性的变化,当属性发生变化时,会通知所有界面中用到该属性的地方,让界面发生刷新
反之,如果一开始属性并没有加在state中,而后面我们希望将它变成响应式的属性
比如我们想在一个对象中加入address属性,需要使用Vue.set
添加,使用Vue.delete
删除实现响应式
mutation:{
updateInfo(state){
Vue.set(state.Info,'address','洛杉矶') //此方法为响应式的,添加
Vue.delete(state.Info,'age') //此方法为响应式的,删除
}
}
而单纯的state.Info['address']='洛杉矶'
是无法做到响应式的,即页面不会进行刷新、更改
官方文档中不推荐我们将mutation中的方法名和组件中的方法名用以下方式来写,因为一旦我们出现书写错误,就无法完成回调。
而是建议在store文件夹下新建一个mutation-types.js文件,内部书写export const INCREMENT = 'increment'
类似这种写法的导出
之后在mutation及组件内部想使用时,只需要
mutation方法中
mutaton:{
[INCREMENT](state){
state.count++
}
}
组件内部
methods:{
addition(){
this.$store.commit(INCREMENT)
}
}
action的基本代码书写:action中的方法默认传入context参数,此时表示store对象
mutation:{
updateInfo(){
state.Info.name = 'lilei' // state里的状态只能在mutation中更改
}
}
actions:{
aupdateInfo(context,payload){
// 当传入参数时,需要payload
// 此处举例用Promise包装了异步操作
return new Promise((resolve,reject) => {
setTimeOut(() => {
context.commit('updateInfo') // mutation中的方法用commit回调
console.log(payload) //打印‘我是携带的信息’
resolve('11111')
},1000)
})
}
}
组件内部:
methods:{
updateInfo(){
this.$store
.dispatch('aupdateInfo','我是携带的信息') //actions中的方法用dispatch回调
.then(res => {
//promise返回的then在这里书写
console.log(res) //打印11111
})
}
}
const moduleA = {
state:{
name:'zhangsan'
}
mutations:{
updateName(state,payload){
state.name = payload
}
}
actions:{
aupdateName(context){
context.commit('updateName','wangwu')
//这里的commit回调的是当前模块里的mutations中的方法
}
}
getters:{
fullname(state){
return state.name + '1111'
},
fullname3(state,getters,rootState)
}
}
const store = new Vuex.store({
state:{
}
mutations:{
}
getters:{
}
actions:{
}
modules:{
a:moduleA
}
})
组件内部
如果是想调用moduleA里面的state:$store.state.a.name
如果是想调用moduleA里面的getters:$store.getters.fullname
如果是想调用moduleA里面的mutations:$store.commit('updateName')
如果是想调用moduleA里面的actions:$store.dispatch('aupdateName')
在store文件夹下,新建actions.js、getters.js、mutations.js文件以及modules文件夹,使得index.js中的代码更清晰,但是一般state不分离出来
在这些新建的文件中export default {}
导出即可