导航
导航
文章目录
  1. Vuex是什么?
  2. 1.State
    1. 1.1在 Vue 组件中获得数据
    2. 1.2mapState 辅助函数
  3. 2.Getters
    1. 2.1在 Vue 组件中获得Getters数据
    2. 2.2mapGetters 辅助函数
  4. 3.Mutations
  5. 4.Actions
    1. 4.1分发 Action
    2. 4.2mapActions 辅助函数
  6. 5.Modules
  7. 6.项目实践

vuex学习实践笔记

Vuex是什么?

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

栗如(travel store):

1
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
60
61
62
63
64
65
66
67
import * as types from '../types'
//数据
const state = {
travelsList: [],
searchKey: {
page: 0,
limit: 20
},
scroll: true
}
//用户行为(可以处理异步),触发 mutations 来改变 state
const actions = {
/**
* 获取约跑步列表
*/
getTravelsList({ commit }) {
if(state.scroll) {
commit(types.GET_TRAVELS_PAGE_NUM)
commit(types.COM_LOADING_STATUS, true),
commit(types.GET_TRAVELS_SCORLL_STATUS, false)
api.TravelsList()
.then(res => {
console.log(res)
commit(types.COM_LOADING_STATUS, false),
commit(types.GET_TRAVELS_SCORLL_STATUS, true)
commit(types.GET_TRAVELS_LIST, res)
})
}
},
/**
* 参加
*/
joinTravel({ commit }, id) {
...
}
}
//可以过滤 state 中的数据
const getters = {
travelsList: state => state.travelsList,
travelListIndex: state => state.travelsList.slice(0,4)
}
//唯一能改变 state 的方法(纯函数)
const mutations = {
[types.GET_TRAVELS_LIST](state, res) {
if(state.searchKey.page <= 1) {
state.travelsList = res.data
} else {
state.travelsList = state.travelsList.concat(res.data)
}
},
[types.GET_TRAVELS_SEARCH_KEY](state, params) {
state.searchKey = params
},
[types.GET_TRAVELS_PAGE_NUM](state) {
state.searchKey['page'] += 1
},
[types.GET_TRAVELS_SCORLL_STATUS](state, status) {
state.scroll = status
}
}
//导出一个 travel store 模块
export default {
state,
actions,
getters,
mutations
}

每一个 Vuex 应用的核心就是 store(仓库)。”store” 基本上就是一个容器,它包含着你的应用中大部分的状态(state)数据。

  • Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
  • 你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交(commit) mutations。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。

用一张图来理解一下
vuex

客户端(Client) -> action -> mutations -> state -> 客户端

可以看出在vuex中数据是单一流向的:视图(view)触发action,action提交(commit)到mutations,mutations改变state(数据),state的改变,相应的组件也会相应的更新。

1.State

单一状态树,唯一数据源,能够直接清晰的读懂数据的结构。

1.1在 Vue 组件中获得数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//store
const state = {
travelsList: [],
searchKey: {
page: 0,
limit: 20
},
scroll: true
}
//在view中直接获取
data () {
return {
scroll: this.$store.state.scroll
}
},

1.2mapState 辅助函数

1
2
3
4
5
6
7
8
9
10
computed: mapState([
// 映射 this.scroll 为 this.$store.state.scroll
'scroll'
])
//或对象展开运算符
computed: {
...mapState({
'scroll'
})
}

2.Getters

对state数据进行过滤或直接返回

2.1在 Vue 组件中获得Getters数据

1
2
3
4
5
6
7
8
9
10
11
//store
const getters = {
travelsList: state => state.travelsList,
travelListIndex: state => state.travelsList.slice(0,4)
}
//在view中直接获取
data () {
return {
travelListIndex: this.$store.getters.travelListIndex
}
},

2.2mapGetters 辅助函数

1
2
3
4
5
6
7
8
9
10
computed: mapGetters([
// 映射 this.travelListIndex 为 this.$store.state.travelListIndex
'travelListIndex'
])
//或对象展开运算符
computed: {
...mapGetters({
'travelListIndex'
})
}

3.Mutations

要更改 Vuex 的 store 中的数据,唯一方法是提交 mutation。每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行数据更改的地方。

1
2
3
4
5
6
7
8
9
10
11
const mutations = {
//使用常量替代 Mutation 事件类型
[types.GET_TRAVELS_LIST](state, res) {
if(state.searchKey.page <= 1) {
state.travelsList = res.data
} else {
state.travelsList = state.travelsList.concat(res.data)
}
},
...
}

当我们在这改变数据时,其它引用此state数据的 Vue 组件也会自动得到更新。

4.Actions

用户的一些行为,来提交到mutations改变数据。可在这进行异步操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const actions = {
//es6的参数解构
getTravelsList({ commit }) {
if(state.scroll) {
commit(types.GET_TRAVELS_PAGE_NUM)
commit(types.COM_LOADING_STATUS, true),
commit(types.GET_TRAVELS_SCORLL_STATUS, false)
api.TravelsList()
.then(res => {
console.log(res)
commit(types.COM_LOADING_STATUS, false),
commit(types.GET_TRAVELS_SCORLL_STATUS, true)
commit(types.GET_TRAVELS_LIST, res)
})
}
},
joinTravel({ commit }, id) {
...
}
}

4.1分发 Action

1
2
3
4
5
created() {
if (this.travelListIndex.length == 0) {
this.$store.dispatch('getTravelsList')
}
},

4.2mapActions 辅助函数

1
2
3
4
5
methods: {
...mapActions([
'getTravelsList' // 映射 this.getTravelsList() 为 this.$store.dispatch('getTravelsList')
]),
}

5.Modules

当应用变得很大时,store 对象会变得臃肿不堪。为了解决这个问题,Vuex 允许我们将 store 分割到模块(module)。每个模块拥有自己的 state、mutation、action、getters

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const moduleA = {
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: { ... },
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态

6.项目实践