Vuex

WGenji Lv4

Vuex

Vuex是vue项目中实现大范围数据共享的技术方案

作用:能够方便、高效地实现组件之间的数据共享

image-20230116161943746

  1. 数据的存取一步到位,不需要层层传递

  2. 数据的流动非常清晰,记录每次操作的痕迹

  3. 存储在Vuex中的数据都是响应式的

安装配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//1.下包
//2.导入
import Vuex from 'vuex'
//3.安装插件
Vue.use(Vuex)
//4.创建Store 对象
const store = new Vuex.Store({
state:{

},
mutations:{

}
})
//5.挂载到vue对象上
new Vue({
render: h=> h(app),
store
}).$mount('#app')

State

概念:本质上就是一个对象

作用:存储全局共享的数据

1
2
3
4
5
new Vuex.Store({
state:{
count: 0
}
})
1
2
3
<p>
count:{{this.$store.state.count}}
</p>

mapState

作用:简化属性名

将store中指定的数据,映射为当前组件的计算属性

image-20230116170357834

1
2
3
4
5
6
7
import {mapState} from 'vuex'

export default {
computed: {
...mapState(['count']),
},//展开运算符,将对象的属性展开放到computed对象中
}

Mutations

背景:直接修改会导致来源不明确的问题,不 方便调试和维护

概念:同步函数,专门用来变更Store中的数据

作用:所有组件都通过mutation修改,可以追踪state的每一次变化,确保修改来源的唯一性

image-20230117151044889

1
2
3
4
5
6
7
new Vuex.Store({
mutations:{
add(state) {
state.count++
}
}
})
1
2
3
4
5
methods:{
btn(){
this.$store.commit('add')
}
}//组件commit调用

Payload

载荷就是参数的意思,通过载荷可以提高Mutation方法的通用性

1
2
3
add(){
this.$store.commit('add', 1)
}
1
2
3
4
5
mutations: {
add(state,payload) {
state.count += payload
}
}//payload只能有一个,如果多个参数可以写成对象形式

mapMutations

把Store中指定的mutation,映射为当前组件的methods

1
<div @click="add(1)">+1</div>
1
2
3
4
5
6
7
import {mapMutations} from 'vuex'

export default {
methods:{
...mapMutations(['add'])
},
}

Actions

背景:为了保证state的每次变化可追踪,Mutation必须是同步函数

概念:专门用来处理Vuex中的异步操作

image-20230117163055599

1
2
3
4
5
6
7
8
9
10
new Vuex.Store({
actions: {
asyncAdd(context, payload){
//context可以理解为简化版的store对象
setTimeout(()=>{
context.commit('add',payload)
}, 1000)
}
}
})
1
2
3
4
5
methods:{
btn(){
this.$store.dispatch('asyncAdd', 1)
}
}//组件dispatch调用

mapActions

把Store中指定的action,映射为当前组件的methods

1
<div @click="addAsync(10)">+10</div>
1
2
3
4
5
6
7
import {mapActions} from 'vuex'

export default {
methods:{
...mapActions(['asyncAdd'])
},
}

Getters

背景:组件中的计算属性复用性比较低

概念:Vuex中的计算属性

作用:当数据发生变化时,Getter的返回值就会自动更新

1
2
3
4
5
6
7
new Vuex.Store({
getters: {
isAllDone(state){
return state.list.evey(i => i.isDone)
}
}
})
1
2
3
<p>
所有任务的完成情况:{{$store.getters.isAllDone}}
</p>

mapGetters

把getter映射为当前组件的计算属性

1
2
3
4
5
6
7
8
import {mapGetters} from 'vuex'

export default {
name: 'Left',
computed:{
...mapGetters(['isAllDone'])
}
}

Modules

背景:随着项目的工程量变大,数据越来越复杂

概念:按照模块化把不同业务的数据和方法进行封装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// store/index.js

//导入
import Vuex from 'vuex'
import Vue from 'vue'
//安装
Vue.use(Vuex)
//导入子模块
import shopcar from './shopcar'
//创建Store对象
const store = new Vuex.Store({
//注册子模块
modules:{
shopcar
}
})
//导出store对象
export default store
1
2
3
4
5
6
7
8
// store/shopcar.js

export default {
state: () => ({}),
mutations: {},
actions: {},
getters: {}
}

namespaced

背景:不同子模块相同的名称方法被调用,会都调用一遍

概念:命名空间

作用:解决不同模块之间成员名称冲突的问题,建议每个模块都开

1
2
3
4
5
6
7
8
9
// store/shopcar.js
export default {
namespaced: true,
mutations:{
test(){

}
}
}
1
2
3
<button @click="$store.commit('shopcar/test')">
</button>
<p>{{$store.state.shopcar.name}}</p>

mapState

1
2
3
computed:{
...mapState('子模块名',['数据名'])
}
  • Title: Vuex
  • Author: WGenji
  • Created at : 2024-08-26 13:51:51
  • Updated at : 2024-08-26 13:51:51
  • Link: https://redefine.ohevan.com/2024/08/26/vue2/4.vuex/
  • License: This work is licensed under CC BY-NC-SA 4.0.