Vuex 的使用方法
# vuex
vuex 也是 vue 全家桶里面的一员,主要是用来管理组件状态的。
之前我们组件之间如何进行状态的交互?
之前我们讲了父传子使用 props,子传父使用自定义事件。
但是如果项目一大,就非常的麻烦。
通过 vuex ,我们就可以很轻松的管理我们的数据状态。
vuex 的核心思想,就是通过一个状态仓库来管理数据。
要使用 vuex,和 vue-router一样,首先需要安装:
npm i vuex
快速入门示例:
// 这个 index.js 就用来管理组件的状态
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
// state 存储整个数据
// getters 类似于计算属性
// mutation 修改仓库数据
// action 异步操作仓库的数据
export default new Vuex.Store({
state : {
stus : [
{name : 'william',age : 18},
{name : 'qingqing',age : 19},
{name : 'shasha',age : 18}
]
},
getters : {},
mutations : {},
actions : {}
})
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
接下来,我们在组件中,就可以直接从仓库拿数据:
<template>
<div>
<ul>
<li v-for="(item,index) in stuList" :key="index">
<p>name : {{item.name}}</p>
<p>age : {{item.age}}</p>
</li>
</ul>
</div>
</template>
<script>
export default {
computed : {
stuList(){
return this.$store.state.stus
}
}
}
</script>
<style lang="scss" scoped>
</style>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# getters
一般说来,我们不会直接拿 state 的数据,一般通过 getters 来拿数据。
getter 类似于组件里面的计算属性,可以对数据进行一个二次处理。
示例如下:
// 这个 index.js 就用来管理组件的状态
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
// state 存储整个数据
// getters 类似于计算属性
// mutation 修改仓库数据
// action 异步操作仓库的数据
export default new Vuex.Store({
state : {
stus : [
{name : 'william',age : 18},
{name : 'qingqing',age : 19},
{name : 'shasha',age : 18}
]
},
getters : {
newStus(state){
return state.stus.map(item=>{
return {
name : `***${item.name}***`,
age : item.age * 3
}
})
}
},
mutations : {},
actions : {}
})
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
之后组件获取数据,方式如下:
export default {
computed : {
stuList(){
return this.$store.getters.newStus
}
}
}
2
3
4
5
6
7
# mutations
到目前为止,我们就知道了如何从仓库获取数据。
我们还需要一个操作,就是修改仓库里面的数据。
修改数据可以使用 mutations,他可以同步修改仓库里面的数据。
首先,我们需要在 mutations 里面定义修改仓库数据的方法,如下:
// 这个 index.js 就用来管理组件的状态
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
// state 存储整个数据
// getters 类似于计算属性
// mutation 修改仓库数据
// action 异步操作仓库的数据
export default new Vuex.Store({
state : {
stus : [
{name : 'william',age : 18},
{name : 'qingqing',age : 19},
{name : 'shasha',age : 18}
]
},
getters : {
newStus(state){
return state.stus.map(item=>{
return {
name : `***${item.name}***`,
age : item.age * 3
}
})
}
},
mutations : {
// 因为我们的数据是放在仓库的
// 所以修改仓库数据的方法也应该写在仓库文件里面
// 写在 mutations 里面
addAge(state,payload){
state.stus.forEach(item=>{
item.age += payload;
})
},
minusAge(state,payload){
state.stus.forEach(item=>{
item.age -= payload;
})
}
},
actions : {}
})
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
接下来,如果某一个组件要修改仓库的数据,直接调用mutation 里面的方法即可。
通过 commit 方法来调用 store 里面的方法。
<template>
<div class="test">
<button @click="add">+30</button>
<button @click="minus">-15</button>
<ul>
<li v-for="(item,index) in stuList" :key="index">
<p>name : {{item.name}}</p>
<p>age : {{item.age}}</p>
</li>
</ul>
</div>
</template>
<script>
export default {
computed : {
stuList(){
return this.$store.getters.newStus
}
},
methods : {
add(){
// 我要做的就是一个事情
// 调用 mutation 里面的方法
this.$store.commit('addAge',10)
},
minus(){
this.$store.commit('minusAge',5)
}
}
}
</script>
<style scoped>
.test {
width: 1200px;
margin: 0 auto;
}
</style>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# action
我们要修改仓库里面的数据,我们现在已经知道,可以使用 mutation 里面定义方法来进行修改。
但是我们的修改可以总结成两种情况:同步修改和异步修改。
同步修改就是像上面一样,在mutation里面定义方法,然后在组件里面commit mutation里面的方法即可。
但是如果是异步,直接使用 mutation的话,会带来调试上面的不方便。
所以当我们拥有异步操作的时候,将异步的操作放在actions里面
// 这个 index.js 就用来管理组件的状态
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
// state 存储整个数据
// getters 类似于计算属性
// mutation 修改仓库数据
// action 异步操作仓库的数据
export default new Vuex.Store({
state : {
stus : [
{name : 'william',age : 18},
{name : 'qingqing',age : 19},
{name : 'shasha',age : 18}
]
},
getters : {
newStus(state){
return state.stus.map(item=>{
return {
name : `***${item.name}***`,
age : item.age * 3
}
})
}
},
mutations : {
// 因为我们的数据是放在仓库的
// 所以修改仓库数据的方法也应该写在仓库文件里面
// 写在 mutations 里面
addAge(state,payload){
state.stus.forEach(item=>{
item.age += payload;
})
},
addAge2(state,payload){
state.stus.forEach(item=>{
item.age += payload;
})
},
minusAge(state,payload){
state.stus.forEach(item=>{
item.age -= payload;
})
}
},
actions : {
// 所有的异步操作都放在 actions 里面
// actions 里面不直接修改数据
// 修改数据还是依赖于 mutation 去修改
ageAdd(state, payload){
setTimeout(()=>{
state.commit('addAge2',payload)
},3000)
}
}
})
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
需要注意,actions不会直接修改仓库的状态,actions只是间接的去调用 mutation。
接下来在组件里面,也就不在 commit mutation,而是 dispatch action
addAge(){
// this.$store.commit('addAge2',100)
this.$store.dispatch('ageAdd',100)
}
2
3
4
# modules
目前为止,我们一个应用的所有状态数据都交给 store/index.js 来进行管理的。
但是在开发大型应用的时候,我们肯定会对模块进行一个拆分。
const moduleA = {
state : {...},
mutations : {...},
getters : {...}
}
const moduleB = {
state : {...},
mutations : {...},
getters : {...}
}
const store = new Vuex.Store({
modules : {
a : moduleA,
b : moduleB
}
})
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
来看一个具体的示例:
首先定义两个模块:
// 这个模块负责管理一组数据
// William
export default {
namespaced : true,
state: {
stus: [
{ name: 'william', age: 18 },
{ name: 'qingqing', age: 18 },
{ name: 'shasha', age: 18 }
]
},
getters: {
stuList(state) {
return state.stus.map(item => {
return {
name: `**${item.name}**`,
age: item.age * 2
}
})
}
},
mutations: {
addAge(state, payload) {
state.stus.forEach(item => {
item.age += payload;
})
}
},
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// 这个模块负责管理一组数据
// f71
export default {
namespaced : true,
state: {
stus: [
{ name: 'zhangsan', age: 18 },
{ name: 'lisi', age: 18 },
{ name: 'TTT', age: 18 }
]
},
getters: {
stuList(state) {
return state.stus.map(item => {
return {
name: `**${item.name}**`,
age: item.age * 2
}
})
}
},
mutations: {
minusAge(state, payload) {
state.stus.forEach(item => {
item.age -= payload;
})
}
},
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
接下来在 vuex 的index.js 文件中,注册模块,如下:
import Vue from 'vue'
import Vuex from 'vuex'
import William from './William'
import f71 from './f71'
Vue.use(Vuex)
export default new Vuex.Store({
modules : {
William,
f71
}
})
2
3
4
5
6
7
8
9
10
11
12
13
14
最后,在组件中使用数据,注意不同的模块需要添加前缀
<template>
<div class="about">
<button @click="addAge">+1</button>
<button @click="minusAge">-1</button>
<ul>
<li v-for="(item,index) in William" :key="index">
<p>{{item.name}}</p>
<p>{{item.age}}</p>
</li>
</ul>
<ul>
<li v-for="(item,index) in f71" :key="index">
<p>{{item.name}}</p>
<p>{{item.age}}</p>
</li>
</ul>
</div>
</template>
<script>
export default {
computed : {
William(){
// return this.$store.state.William.stus
return this.$store.getters['William/stuList']
},
f71(){
// return this.$store.state.f71.stus
return this.$store.getters['f71/stuList']
}
},
methods : {
addAge(){
this.$store.commit('William/addAge',1);
},
minusAge(){
this.$store.commit('f71/minusAge',1);
}
}
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42