本文主要通過簡單的理解來解釋下vuex的基本流程,而這也是vuex難點之一。
首先我們先了解下vuex的作用
vuex其實是集中的數據管理倉庫,相當於數據庫mongoDB,MySQL等,任何組件都可以存取倉庫中的數據。
vuex流程與vue類比
我們看一下一個簡單的vue響應式的例子,vue中的data 、methods、computed,可以實現響應式。
視圖通過點擊事件,觸發methods中的increment方法,可以更改state中count的值,一旦count值發生變化,computed中的函數能夠把getCount更新到視圖。
<div id="app">
<button @click="increment"></button>
{{getcount}}
</app>
new Vue({
el: "#app",
// state
data () {
return {
count: 0
}
},
// actions
methods: {
increment () {
this.count++
}
},
// view
computed: {
getCount(){
return this.count
}
},
})
那vuex和這個vue響應式例子有什么關系呢?
我們也可以用vuex來實現同樣的功能,來實現vuex與vue的類比。
其實原理都是一樣的,在vuex中有四個部分:state 、 mutations 、 actions 、getters
類比:
可以先假設沒有 actions的情況下:
他們的對應關系是這樣的:
更改數據 mutations->methods
獲取數據 getters -> computed
數據 state->data
視圖通過點擊事件,觸發mutations中方法,可以更改state中的數據,一旦state數據發生更改,getters把數據反映到視圖。
那么action 又是做什么的呢,可以理解是為了處理異步,而單純多加的一層。要是沒有設計上可以沒有這一步。
那可能很多人有疑問,dispatch,commit,又是做什么的呢?
是時候拿出這張圖了:
在vue例子中,我們觸發的click事件,就能觸發methods中的方法,這是vue設計好的。而在vuex中則不行了,一定要有個東西來觸發才行,就相當於自定義事件on,emit。vuex中的action,mulation通過on自定義的方法,相應的需要emit來觸發。
他們的關系是這樣的: 通過dispatch可以觸發actions中的方法,actions中的commit可以觸發mulations中的方法。
我們來看看vuex的示例,來實現vue的同樣功能
const store = new Vuex.Store({
state: {
count: 0
},
//state的值只能通過mutations來修改
mutations: {
increment(state) {
state.count++
}
},
//this.$store.commit("increment")觸發mutations中函數"increment"
actions: {
increment({commit}) {
commit("increment"); //this.$store.commit("increment")
}
},
//通過getter中的方法來獲取state值
getters: {
getCount(state) {
return state.count
}
}
})
export default store
App.vue
<template>
<div id="app">
<button @click="increment">增加</button>
{{this.$store.getters.getCount}}
</div>
</template>
<script>
export default {
methods: {
increment(){
//this.$store.dispatch("increment")觸發actions函數"increment"
this.$store.dispatch("increment")
}
}
}
</script>
上面例子中actions和mulations的函數名都是一樣的,為了方便理解,我把名字取成不一樣的,來幫助大家理解。
更改increment函數名-驗證對應關系
通過dispatch-actions ,commit-mutation 找到了他們之間的連接關系
store.js
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
incrementMutations(state) {
return state.count++
}
},
actions: {
incrementActions({commit}) {
commit("incrementMutations");
}
},
//通過getter中的方法來獲取state值
getters: {
getCount(state) {
return state.count
}
}
})
export default store
main.js
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')
App.vue
<template>
<div id="app">
<div id="app">
<button @click="incrementClick">增加</button>
{{this.$store.getters.getCount}}
</div>
</div>
</template>
<script>
export default {
methods: {
incrementClick(){
this.$store.dispatch("incrementActions")
}
}
}
</script>
參考資料:
本文的圖片來源一篇英文文章:Intro to Vuex,感興趣的可以去看下。