Vuex是实现组件全局状态(数据)管理的一种机制,可以方便的实现组件之间的数据共享
使用Vuex管理数据的好处:
- 能够在vuex中集中管理共享的数据,便于开发和后期进行维护
- 能够高效的实现组件之间的数据共享,提高开发效率
- 存储在vuex中的数据是响应式的,当数据发生改变时,页面中的数据也会同步更新
2.Vuex的基本使用
1. 初始化 Vuex 实例
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
}
})
在main.js中引入store
import Vue from 'vue'
import App from './App.vue'
import store from './store'
Vue.config.productionTip = false
new Vue({
store,
render: h => h(App)
}).$mount('#app')
2.Vuex中的五个基本属性
Vuex 的内脏由五部分组成:State
、Getter
、Mutation
、Action
和 Module
state
:vuex的基本数据,用来存储变量geeter
:从基本数据(state)派生的数据,相当于state的计算属性mutation
:提交更新数据的方法,必须是同步的(如果需要异步使用action)。每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数,提交载荷作为第二个参数。action
:和mutation的功能大致相同,不同之处在于 ==》1. Action 提交的是 mutation,而不是直接变更状态。 2. Action 可以包含任意异步操作。modules
:模块化vuex,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理。
3.以加法计算器为例
store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
count: 0
},
// 只有 mutations 中定义的函数,才有权利修改 state 中的数据
mutations: {
add(state) {
// 不要在 mutations 函数中,执行异步操作
// setTimeout(() => {
// state.count++
// }, 1000)
state.count++
},
addN(state, step) {
state.count += step
},
sub(state) {
state.count--
},
subN(state, step) {
state.count -= step
}
},
actions: {
addAsync(context) {
setTimeout(() => {
// 在 actions 中,不能直接修改 state 中的数据;
// 必须通过 context.commit() 触发某个 mutation 才行
context.commit('add')
}, 1000)
},
addNAsync(context, step) {
setTimeout(() => {
context.commit('addN', step)
}, 1000)
},
subAsync(context) {
setTimeout(() => {
context.commit('sub')
}, 1000)
},
subNAsync(context, step) {
setTimeout(() => {
context.commit('subN', step)
}, 1000)
}
},
getters: {
showNum(state) {
return '当前最新的数量是【' + state.count + '】'
}
}
})
Addition.vue
采用$store
直接调用
<template>
<div>
<!-- <h3>当前最新的count值为:{{$store.state.count}}</h3> -->
<h3>{{$store.getters.showNum}}</h3>
<button @click="btnHandler1">+1</button>
<button @click="btnHandler2">+N</button>
<button @click="btnHandler3">+1 Async</button>
<button @click="btnHandler4">+N Async</button>
</div>
</template>
<script>
export default {
data() {
return {}
},
methods: {
btnHandler1() {
this.$store.commit('add')
},
btnHandler2() {
// commit 的作用,就是调用 某个 mutation 函数
this.$store.commit('addN', 3)
},
// 异步地让 count 自增 +1
btnHandler3() {
// 这里的 dispatch 函数,专门用来触发 action
this.$store.dispatch('addAsync')
},
btnHandler4() {
this.$store.dispatch('addNAsync', 5)
}
}
}
</script>
Subtraction.vue
import
导入后调用
<template>
<div>
<!-- <h3>当前最新的count值为:{{count}}</h3> -->
<h3>{{showNum}}</h3>
<button @click="btnHandler1">-1</button>
<button @click="subN(3)">-N</button>
<button @click="subAsync">-1 Async</button>
<button @click="subNAsync(5)">-N Async</button>
</div>
</template>
<script>
import { mapState, mapMutations, mapActions, mapGetters } from 'vuex'
export default {
data() {
return {}
},
computed: {
...mapState(['count']),
...mapGetters(['showNum'])
},
methods: {
...mapMutations(['sub', 'subN']),
...mapActions(['subAsync', 'subNAsync']),
btnHandler1() {
this.sub()
}
}
}
</script>
两种使用方式没有强制要求,个人倾向于第一种。
特别注意:
- 不要在
mutations
函数中,执行异步操作, 得在actions
中操作 - 在
actions
中,不能直接修改state
中的数据,必须通过context.commit()
触发某个mutation
才行