vuex中,有默认的五种基本的对象
1.state:存储状态(变量)
2.getters:对数据获取之前的再次编译,可以理解为state的计算属性。我们在组件中使用 $sotre.getters.fun()
3.mutations:修改状态,并且是同步的。在组件中使用$store.commit(‘’,params)。这个和我们组件中的自定义事件类似。
4.actions:异步操作。在组件中使用是$store.dispath(‘’)
5.modules:store的子模块,为了开发大型项目,方便状态管理而使用的。这里我们就不解释了,用起来和上面的一样。
首先新建一个vue项目,用来测试:1
2
3
4
5
6vue init webpack vuex
cd app/
npm run dev
src 下创建文件夹vuex
vuex 文件夹下创建 store.js 文件夹modules
modules 文件夹下创建app.js user.js
目录如下:
安装vuex1
npm install vuex --save
安装成功之后,将vuex引入项目中:
store.js1
2
3
4
5
6
7
8
9
10
11
12
13import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const state = {
name: '小张'
}
const store = new Vuex.Store({
state
})
export default store
自此你可以开始用vuex了
接下来,在main.js中引入store.js1
2
3
4
5
6
7
8
9
10
11
12
13import Vue from 'vue'
import App from './App'
import router from './router'
import store from './vuex/store' // 引入store
Vue.config.productionTip = false
new Vue({
el: '#app',
router,
store,
components: { App },
template: '<App/>'
})
完整APIdemo地址:GitHub
运行效果如下:
关键代码:
store.js1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24import Vue from 'vue'
import Vuex from 'vuex'
import app from './modules/app'
import user from './modules/user'
Vue.use(Vuex)
const state = {
name: '小张'
}
// export default new Vuex.Store({
// state1
// })
const store = new Vuex.Store({
state,
modules: {
app,
user
}
})
export default store
app.js1
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
28const app = {
state: {
appConut: 0
},
getters: {
watchAppConut: state => {
return state.appConut + 100
}
},
mutations: {
ADD_APP_COUNT: (state, n) => {
state.appConut += n
},
DELETE_APP_COUNT: (state, n) => {
state.appConut -= n
},
RESET_APP_COUNT: (state, n) => {
state.appConut = n
}
},
actions: {
ACCTION_APP_COUNT: ({ commit }, mes) => {
commit('RESET_APP_COUNT', mes)
}
}
}
export default app
user.js1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23const user = {
state: {
userConut: 0
},
mutations: {
ADD_USER_COUNT: (state, n) => {
state.userConut += n
},
DELETE_USER_COUNT: (state, n) => {
state.userConut -= n
},
RESET_USER_COUNT: (state, n) => {
state.userConut = n
}
},
actions: {
ACCTION_USER_COUNT: ({ commit }, mes) => {
commit('RESET_USER_COUNT', mes)
}
}
}
export default user
HelloWorld.vue1
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
68<template>
<div class="hello">
<div>
<div>mapState简写:{{ name }}</div>
<div>app中的appConut:{{ $store.state.app.appConut}}</div>
<div>mapState简写:{{ appConut }}</div>
<div>app中计算属性(appConut+100)watchAppConut:{{ $store.getters.watchAppConut}}</div>
<div>watchAppConut(mapGetters简写):{{ watchAppConut}}</div>
<button @click="clickAppAdd(100)">+</button>
<button @click="clickAppDelete">-</button>
<button @click="clickActionsApp('置空')">actions</button>
</div>
<div>
<div>user中的userConut:{{ $store.state.user.userConut}}</div>
<button @click="clickUserAdd">+</button>
<button @click="clickUserDelete">-</button>
<button @click="clickActionsUser">actions</button>
</div>
</div>
</template>
<script>
import { mapState, mapMutations, mapActions, mapGetters } from 'vuex'
export default {
name: 'HelloWorld',
data () {
return {
msg: 'Welcome to Your Vue.js App'
}
},
// computed: mapState(['name']), // 这样写更简单
computed: {
...mapState({
name: 'name',
appConut: state => state.app.appConut
}),
...mapGetters(
['watchAppConut']
)
},
methods: {
...mapMutations({
clickAppAdd: 'ADD_APP_COUNT'
}),
// clickAppAdd() {
// this.$store.commit('ADD_APP_COUNT', 1)
// },
clickAppDelete() {
this.$store.commit('DELETE_APP_COUNT', 1)
},
...mapActions({
clickActionsApp: 'ACCTION_APP_COUNT'
}),
// clickActionsApp() {
// this.$store.dispatch('ACCTION_APP_COUNT')
// },
clickUserAdd() {
this.$store.commit('ADD_USER_COUNT', 2)
},
clickUserDelete() {
this.$store.commit('DELETE_USER_COUNT', 2)
},
clickActionsUser() {
this.$store.dispatch('ACCTION_USER_COUNT', '置空')
},
}
}
</script>
state
vuex的state和vue的data有很多相似之处,都是用于存储一些数据,或者说状态值.这些值都将被挂载 数据和dom的双向绑定事件,也就是当你改变值的时候可以触发dom的更新.
使用:this.$store.state.name/$store.state.app.appConut(见 demo 的 HelloWorld.vue)
为了防止store过于臃肿,只有state在取值的时候需要分块的,getters/mutations/actions 的调用是全局的。
mutations
app.js1
2
3
4
5
6
7
8
9
10
11mutations: {
ADD_APP_COUNT: (state, n) => {
state.appConut += n
},
DELETE_APP_COUNT: (state, n) => {
state.appConut -= n
},
RESET_APP_COUNT: (state, n) => {
state.appConut = n
}
}
HelloWorld.vue 调用1
2
3clickAppAdd() {
this.$store.commit('ADD_APP_COUNT', 1)
}
mapMutations
HelloWorld.vue1
2
3
4
5
6import { mapState, mapMutations, mapActions, mapGetters } from 'vuex'
...mapMutations({
clickAppAdd: 'ADD_APP_COUNT'
})
参数不用管,vuex以帮你处理
actions
app.js1
2
3
4
5actions: {
ACCTION_APP_COUNT: ({ commit }, mes) => {
commit('RESET_APP_COUNT', mes)
}
}
HelloWorld.vue1
2
3clickActionsApp() {
this.$store.dispatch('ACCTION_APP_COUNT')
}
mutations 使用 $store.commit 调用,必须是同步的;actions 使用 $store.dispatch 调用通知,并且用commit 调用mutations 来修改数据,这个是异步操作使用的。
mapActions
HelloWorld.vue1
2
3
4
5import { mapState, mapMutations, mapActions, mapGetters } from 'vuex'
...mapActions({
clickActionsApp: 'ACCTION_APP_COUNT'
})
getters
app.js1
2
3
4
5getters: {
watchAppConut: state => {
return state.appConut + 100
}
}
HelloWorld.vue1
2<div>app中计算属性(appConut+100)watchAppConut:{{ $store.getters.watchAppConut}}</div>
<div>watchAppConut(mapGetters简写):{{ watchAppConut}}</div>
mapGetters
app.js1
2
3
4
5getters: {
watchAppConut: state => {
return state.appConut + 100
}
}
HelloWorld.vue1
2
3
4
5computed: {
...mapGetters(
['watchAppConut']
)
}
1 | <div>app中计算属性(appConut+100)watchAppConut:{{ $store.getters.watchAppConut}}</div> |
modules
可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16const moduleA = {
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: { ... },
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB})