最近一直在自學vuex,官方文檔剛開始看不懂,網上又看了很多資料,但是卻越看越迷糊。自己稍微有了一點感悟以後,把它寫下來,一方面爲了梳理,另一方面可以分享出來供大家參考。
1.vuex的本質其實就是各個組件之間的響應式通信。
比如我們有一個表單組件,表單組件又包含了幾個子組件,當子組件的數據和父組件的數據或者各個子組件數據之間發生交互的時候,它們之間的通信就會變得很麻煩。
2.安裝、使用 vuex
npm install vuex --save
在src目錄下面創建一個vuex模塊,然後在下面創建store.js
store.js如下:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state:{
count:1
}
});
然後在main.js裏面引入並註冊 如下
import Vue from 'vue'
import App from './App'
import router from './router'
import store from './vuex/store'
new Vue({
el: '#app',
router,
store,
components: { App },
template: '<App/>'
})
我們可以在官方文檔下面看到store對象下面主要有1.state 2.getter 3.mutation 4.action 5.module 五個模塊。現在我們來通俗的解釋一下這五個模塊。
1) state
最簡單的store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state:{
count:1
}
});
在App.vue中
<template>
<div id="app">
<h1>{{getCount}}</h1>
<h1>{{count}}</h1>
<h1>{{c}}</h1>
</div>
</template>
<script>
import { mapState } from 'vuex'
export default {
name:'App',
computed:{
getCount:function() {
return this.$store.state.count
},
...mapState([
'count'//這種情況下count和store下的state中的count名字要一樣
]),
...mapState({
c:state => state.count
})
}
}
</script>
這樣之後state中的count在我們項目中的任何組件下都可以訪問到,其實在我的理解下就相當於我們js中的全局變量一樣。
還有,我們看到computed下面有三種方式,其實這三種方式表達的意思是一模一樣的,頁面顯示的結果也是一樣。第二種和第三種方法用到了es6的語法,可以自己去看,不再解釋。
2)getter
getters 和 vue 中的 computed 類似 , 都是用來計算 state 然後生成新的數據 ( 狀態 ) 的。
(無非就是利用state中的數據,然後經過我們的處理變成我們想要的數據)
store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state:{
count:1
},
getters: {
getCount: state => {
return state.count+1;
}
}
});
App.vue
<template>
<div id="app">
<h1>{{count}}</h1>
<h1>{{getCount}}</h1>
</div>
</template>
<script>
import { mapState } from 'vuex'
import { mapGetters } from 'vuex'
export default {
name:'App',
computed:{
count(){
return this.$store.getters.getCount
},
...mapGetters([
'getCount'
])
}
}
3)mutation
我們已經有了“全局變量”state下的count,和能處理count的getter,那麼當我們想要改變count的時候,mutation就派上用場了。
官方的解釋:
更改 Vuex 的 store 中的狀態的唯一方法是提交 mutation。Vuex 中的 mutation 非常類似於事件:每個 mutation 都有一個字符串的 事件類型 (type) 和 一個 回調函數(handler)。這個回調函數就是我們實際進行狀態更改的地方,並且它會接受 state 作爲第一個參數
store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state:{
count:1
},
mutations: {
increment (state,payload){
state.count += payload.amount;
}
}
});
App.vue
<template>
<div id="app">
<h1 @click="increment">{{count}}</h1>
<h1 @click="dispatch">{{count}}</h1>
</div>
</template>
<script>
import { mapMutations } from 'vuex'
import { mapState } from 'vuex'
export default {
name: 'App',
computed:{
...mapState([
'count'
]),
},
methods:{
...mapMutations([
'increment'
]),
dispatch: function() {
this.$store.commit('increment')
}
}
}
</script>
需要主要的是mutation中的方法是不可以進行異步操作的,想要異步操作,我們需要引出actions
4)actions
多個 state 的操作 , 使用 mutations 會來觸發會比較好維護 , 那麼需要執行多個 mutations 就需要用 action 了
store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state:{
count:16
},
getters: {
getCount: state => {
return state.count+578;
}
},
mutations: {
increment (state,payload){
state.count += payload.amount;
}
},
actions: {
increment (context) {
context.commit('increment')
}
}
});
App.vue
<template>
<div id="app">
<<h1 @click="increment">{{count}}</h1>
<h1 @click="add">{{count}}</h1>
</div>
</template>
<script>
import { mapActions} from 'vuex'
import { mapState } from 'vuex'
export default {
name: 'App',
computed:{
...mapState([
'count'
]),
},
methods:{
...mapActions([
'increment'// 將 `this.increment()` 映射爲 `this.$store.dispatch('increment')`
])
...mapActions({
add:'increment'
}),
}
}
</script>
5)Module
module類似於將store模塊化,變成一個一個的小模塊
由於使用單一狀態樹,應用的所有狀態會集中到一個比較大的對象。當應用變得非常複雜時,store 對象就有可能變得相當臃腫。
爲了解決以上問題,Vuex 允許我們將 store 分割成模塊(module)。每個模塊擁有自己的
state、mutation、action、getter、甚至是嵌套子模塊——從上至下進行同樣方式的分割:
store.js
import Vue from 'vue';
import Vuex from 'vuex';
import index from './store/index';
Vue.use(Vuex);
export default new Vuex.Store({
modules: {
index: index
},
});
index.js
export default {
state:{
count:16
},
getters: {
getCount: state => {
return state.count+578;
}
},
mutations: {
increment (state,payload){
state.count += payload.amount;
}
},
actions: {
increment (context) {
context.commit('increment')
}
}
}
大體上就是這麼回事,看懂這些,再去看官方的文檔就會覺得很簡單,不要被其他一些文章嚇到。