一、State单一状态树
(1)引例:
在我们的生活中有很多的信息需要被记录,比如上学时的个人档案,从小学到大学每个阶段都有信息记录,如果这些信息被分散到很多地方进行管理,有一天你需要办理某个业务时,你会发现你需要到各个对应的工作地点去打印盖章等各种资料信息,最后到一个地方提交你的消息无误的证明。这种保存信息的方式,不仅低效且难以管理。
(2)对比应用开发:
如果你的状态信息是保存到多个Store对象中的,那么之后的管理和维护等等都会变得特别困难。所以Vuex也使用了单一状态树来管理应用层级的全部状态。单一状态树((单一数据源)在一个项目里面只有一个store)能够让我们最直接的方式找到某个状态的片段,而且在之后的维护和调试过程中,也可以非常方便的管理和维护。
(3)用法:
在state中保存已经定义好的属性×××,这些属性都会被加入到响应式系统中,而响应式系统会监听属性的变化,当属性发生变化时,会通知所有界面中用到改属性的地方,让界面发生更新。在各个组件中可以通过 this.$store.state.×××
进行访问
(4)小结
state中存储数据,存储状态;在根实例中注册了store 后,用 this.$store.state 来访问;对应vue里面的data;存放数据方式为响应式,vue组件从store中读取数据,如数据发生变化,组件也会对应的更新。
二、Getters基本使用
(1)作用:
从 store 中获取一些 state 变化后的状态,经过变化之后再给组件使用,类似于计算属性computed
(2)用法:
1、基本使用
const store = new Vuex.Store({
state:{
students:[
{id:110,name:'xiaoming',age:18},
{id:111,name:'xiaohong',age:24},
{id:112,name:'xiaoqiang',age:30},
{id:113,name:'xiaohai',age:10}
],
},
}
获取学生年龄大于20的学生
getters:{
more20stu(state) {
return state.students.filter(s => s.age > 20)
}
}
在组件中:
$store.getters.more20stu
2、getters作为参数
getters:{
more20stu(state) {
return state.students.filter(s => s.age > 20)
},
more20stuLength(state,getters) {
return getters.more20stu.length
},
}
在组件中:
$store.getters.more20stuLength
3、getters传递参数
getters:{
moreAgestu(state) {
return age => state.students.filter(s => s.age > age)
}
}
在组件中:
$store.getters.moreAgestu(12)
getters默认是不能传递参数的, 如果希望传递参数, 那么只能让getters本身返回另一个函数。
如上面案例中,我们希望可以获取年龄超过12的学生信息。
三、Mutations
(1)作用:
如果我们想要修改state状态,最好通过mutations修改,因为如果是多个界面都修改state的时候我们不好区分,希望进行跟踪。而在mutations中进行修改,这样Devtools( Vue开发的一个浏览器插件 可以记录每次修改State的状态)才会进行记录,才能跟踪每一步修改的状态,调错的时候就更加方便。注意:mutations中通常做同步操作,异步操作跟踪不到。
(2)用法:
1、mutations状态更新
mutations:{
increment(state) {
state.counter++
}
}
通过mutations进行更新
increment() {
// 通过 commit 进行相关的提交
this.$store.commit('increment')
}
2、mutations传递参数
mutations:{
increment(state,n) {
state.counter++
}
}
传递一个参数
this.$store.commit('increment',2)
如果有很多参数进行传递,我们会以对象的形式进行传递(payload)
mutations:{
increment(state,payload) {
state.counter += payload.count
}
}
也就是payload是一个对象,可以从对象中取出相关信息
普通的提交风格:
increment(){
this.$store.commit('increment',{count:2})
}
特殊的提交风格:
this.$store.commit({
type:'increment',
count
})
四、Actions
(1)作用:
前面强调, 不要在mutations中进行异步操作,但是某些情况, 我们确实希望在Vuex中进行一些异步操作, 比如网络请求, 必然是异步的。这个时候怎么处理呢?Action类似于Mutation, 但是是用来代替Mutation进行异步操作的。
(2)用法:
如果是异步操作想要修改state,需要先在actions中先执行完异步操作后再提交到mutations中进行修改
const store = new Vuex.store({
state:{
count:0
},
mutations:{
increment(state){
state.count++
}
},
actions:{
increment(context){
context.commit('increment')
}
}
})
context是和store对象具有相同方法和属性的对象。也就是说, 我们可以通过context去进行commit相关的操作, 也可以获取context.state等,但是注意, 这里它们并不是同一个对象。
在Vue组件中,如果我们想要调用actions中的方法,那么就需要使用dispatch进行提交
Vue组件中:
methods:{
increment(){
this.$store.dispatch('increment',{count:5})
}
}
store对象中:
mutations:{
increment(state,payload){
state.count += payload.count
}
},
actions:{
increment(context,payload){
setTimeout(() => {
context.commit('increment',payload)
},1000)
}
}
在Action中, 我们可以将异步操作放在一个Promise中, 并且在成功或者失败后, 调用对应的resolve或reject
actions:{
increment(context) {
return new Promise(resolve => {
setTimeout(() => {
context.commit('increment')
resolve()
},1000)
})
}
}
methods:{
increment(){
this.$store.dispatch('increment').then(res => {
console.log('完成了更新操作')
})
}
}
五、Module
(1)作用:
Vue使用单一状态树,那么也意味着很多状态都会交给Vuex来管理。当应用变得非常复杂时,store对象就有可能变得相当臃肿。为了解决这个问题, Vuex允许我们将store分割成模块(Module), 而每个模块拥有自己的state、mutation、action、getters等。
(2)用法:
const moduleA = {
state:{
name:'malong'
},
mutations:{
updateName(state,payload) {
state.name = payload
}
},
actions:{
aUpdateName(context) {
setTimeout(() => {
console.log(context);
context.commit('updateName','xuxin')
},1000)
}
},
getters:{
fullname(state) {
return state.name + '111'
},
fullname2 (state,getters) {
return getters.fullname + '222'
},
// rootState 下面根的 state
fullname3(state,getters,rootState) {
return getters.fullname2 + rootState.counter
}
}
}
const store = new Vuex.Store({
state:{
},
mutations:{
},
actions:{
},
getters:{
},
modules:{
// 这里的a会被放到state中
a: moduleA
}
})