Vuex核心概念
成员列表:
- state 存放状态
- getters 加工state成员给外界
- mutations state成员操作方法
- actions 异步操作
- modules 模块化状态管理
State 单一状态树
Single Source of Truth 单一数据源
只创建一个store,永远对应$store来使用
Getters
相当于计算属性,如果需要对state做一定处理后再交给组件,则使用getters
getters的计算属性会默认传入两个参数(state, getters)
getters:{
doublecounter(state){
return state.counter*2
}
},
<h2>getters演示</h2>
<p>doublecounter:{{$store.getters.doublecounter}}</p>
- 还可以通过第二个参数getters,来实现不同计算属性的互相调用
fourfoldcounter(state,getters){
return getters.doublecounter*2
}
<h2>getters演示</h2>
<p>doublecounter:{{$store.getters.doublecounter}}</p>
<p>fourfoldcounter:{{$store.getters.fourfoldcounter}}</p>
-
如果想要在组件中,对getters的计算属性传入外部参数,需要使用闭包,即return一个函数,把参数传入这个函数并对state进行操作。 multiplecounter(state){
return function(multiple){
return state.counter*multiple
}
}
<p>multiple=8, multiplecounter:{{$store.getters.multiplecounter(8)}}</p>
Mutations
store状态的唯一更新方式是:提交mutations,提交后就会执行指定的函数
-
普通提交:回调函数第一个参数就是state add() {
this.$store.commit('increase')
},
mutations:{
increase(state){
state.counter++
}
}
-
传参提交:commit的第二个参数可以传参,或者通过提交对象实现 举例:增添两个对state加减可变数值的按钮,count为App组件的data,设置为5 <button @click="addcount">+{{count}}</button>
<button @click="subcount">-{{count}}</button>
添加method,commit提交,第二个参数传入count addcount(){
this.$store.commit('increasecount',this.count)
},
subcount(){
this.$store.commit({
type: 'reducecount',
count: this.count
})
}
在mutations中添加两个方法,根据传入的count对state操作 increasecount(state,count){
state.counter +=count
},
reducecount(state,payload){
state.counter -=payload.count
}
-
补充:
-
如果state中的是对象或者数组,需要使用Vue.set 和Vue.delete 方法,才能实现响应式的添加或者删除属性 -
官方推荐新建一个文件定义常量,然后再组件文件和vuex文件分别引入,实现提交方法和mutations 方法的命名统一 INCREASECOUNT(){
this.$store.commit('INCREASECOUNT',this.count)
},
[INCREASECOUNT](state,count){
state.counter +=count
},
Actions
Mutations 应该存放同步操作,如果想用异步操作,需在添加到Mutations前增加一个Actions操作
组件方法使用dispath 方法调用Mutations
actions的函数默认传递参数context 约等于store 对象,类似于Mutations,第二个参数payload用于传参
再在Actions的异步操作中使用context.commit 提交到Mutations的操作
举例:实现异步更新,更新完成返回一个提示信息
- Actions中使用return一个Promise确保异步完成后返回成功提示,在组件方法中使用
.then 把提示显示(进行异步完成后的操作)
Actions中的方法:
actions:{
aupdatepreson(context,payload){
return new Promise((resolve)=>{
setTimeout(() => {
context.commit('updateperson');
console.log('我是payload参数:'+ payload);
resolve('success commit')
}, 1000);
})
}
}
组件中的方法:
aupdate(){
this.$store
.dispatch('aupdatepreson','异步更新传递的参数')
.then(res=>{
console.log(res);
})
}
出现报错bug,解决:sockjs.js?9be2:1606 GET http://192.168.1.101:8080/sockjs-node/info?t=1583642185049 net::ERR_CONNE… - 尚码园 (shangmayuan.com)
modules
由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。
为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块
const moduleA = {
state: { moive: 'Star War'},
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: () => ({ ... }),
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
modules: {
moduleA,
moduleB
}
})
store.state.moduleA.name
store.state.moduleB
模块的局部状态
mutations和getters使用方法和根的一致,方法名不得和根的重复,否则无法正常提交
此处的参数state为moduleA的state(局部state)
第二个参数payload可正常使用
mutations:{
addticket(state){
state.ticket++;
},
}
getters用法和根的一致,getters名不得和根的重复
第一个参数state为moduleA的state(局部state)
第二个参数getter为全局的getters
第三个参数rootState用于获取根state
getters:{
totalprice (state,getters,rootState){
return state.ticket*rootState.price;
}
},
actions:{
}
项目结构
Vuex 并不限制你的代码结构。但是,它规定了一些需要遵守的规则:
- 应用层级的状态应该集中到单个 store 对象中。
- 提交 mutation 是更改状态的唯一方法,并且这个过程是同步的。
- 异步逻辑都应该封装到 action 里面
├── index.html
├── main.js
├── components
│ ├── App.vue
│ └── ...
└── store
├── index.js
├── actions.js
├── mutations.js
├── getters.js
└── modules
└── moduleA.js
- 踩坑:如果某个操作中使用了
vue.set 这样的方法,需要在其抽离的js文件中也引入vue
|