通俗理解vuex原理---通过vue例子类比
本文主要通过简单的理解来解释下vuex的基本流程,而这也是vuex难点之一。
首先我们先了解下vuex的作用
vuex其实是集中的数据管理仓库,相当于数据库mongoDB,MySQL等,任何组件都可以存取仓库中的数据。
vuex流程与vue类比
我们看一下一个简单的vue响应式的例子,vue中的data 、methods、computed,可以实现响应式。
视图通过点击事件,触发methods中的increment方法,可以更改state中count的值,一旦count值发生变化,computed中的函数能够把getCount更新到视图。
1 <div id="app"> 2 <button @click="increment"></button> 3 {{getcount}} 4 </app> 5 6 7 new Vue({ 8 el: "#app", 9 // state 10 data () { 11 return { 12 count: 0 13 } 14 }, 15 16 // actions 17 methods: { 18 increment () { 19 this.count++ 20 } 21 }, 22 23 // view 24 computed: { 25 getCount(){ 26 return this.count 27 } 28 29 }, 30 })
那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的同样功能
1 const store = new Vuex.Store({ 2 3 state: { 4 count: 0 5 }, 6 7 //state的值只能通过mutations来修改 8 mutations: { 9 increment(state) { 10 state.count++ 11 } 12 }, 13 14 //this.$store.commit("increment")触发mutations中函数"increment" 15 actions: { 16 increment({commit}) { 17 commit("increment"); //this.$store.commit("increment") 18 } 19 20 }, 21 22 //通过getter中的方法来获取state值 23 getters: { 24 getCount(state) { 25 return state.count 26 } 27 } 28 }) 29 30 export default store
App.vue
1 <template> 2 <div id="app"> 3 <button @click="increment">增加</button> 4 {{this.$store.getters.getCount}} 5 </div> 6 </template> 7 8 <script> 9 export default { 10 methods: { 11 increment(){ 12 //this.$store.dispatch("increment")触发actions函数"increment" 13 this.$store.dispatch("increment") 14 } 15 } 16 } 17 </script>
上面例子中actions和mulations的函数名都是一样的,为了方便理解,我把名字取成不一样的,来帮助大家理解。
更改increment函数名-验证对应关系
通过dispatch-actions ,commit-mutation 找到了他们之间的连接关系
store.js
1 const store = new Vuex.Store({ 2 state: { 3 count: 0 4 }, 5 mutations: { 6 incrementMutations(state) { 7 return state.count++ 8 } 9 }, 10 11 actions: { 12 incrementActions({commit}) { 13 commit("incrementMutations"); 14 } 15 16 }, 17 18 //通过getter中的方法来获取state值 19 getters: { 20 getCount(state) { 21 return state.count 22 } 23 } 24 }) 25 26 export default store 27 28 29 main.js 30 import Vue from 'vue' 31 import App from './App.vue' 32 import store from './store' 33 34 Vue.config.productionTip = false 35 36 new Vue({ 37 store, 38 render: h => h(App) 39 }).$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>
能理解吧 !