對于state、getter、mutation、action來說,如果每次使用的時候都用this.$store.state、this.$store.getter等參考,會比較麻煩,代碼也重復和冗余,我們可以用輔助函式來幫助我們生成要的代碼,輔助函式有如下四個:
mapState(namespace, map) ;用于獲取state
mapGetters(namespace, map) ;用于獲取getters
mapMutations(namespace, map) ;用于獲取mutations
mapActions(namespace, map) ;用于獲取actions
每個輔助函式都可以帶兩個引數:
namespace ;命名空間,也就是模塊名
map ;要獲取的資訊
map有兩種用法,可以是物件(鍵名是當前Vue實體設定的變數名,值是從store要獲取的變數名)或者字串陣列(此時獲取和設定的變數名為同一個),
注:使用輔助函式需要在根節點注入store
ps:很多新手可能只會使用輔助函式,不知道還可以用this.$store.state,this.$store.getter這些用法...
這些輔助函式回傳的都是一個物件,我們可以配合ES6的物件展開運算子,我們可以極大地簡化寫法,例如:
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Document</title> <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script> <script src="https://unpkg.com/[email protected]/dist/vuex.js"></script></head><body> <div id="app"> <p>{{no}}</p> <p>{{No}}</p> <button @click="test1">測驗1</button> <button @click="test2">測驗2</button> </div> <script> const store = new Vuex.Store({ state:{no:100}, getters:{ No:function(state){return state.no+100} }, mutations:{ increment(state,payload){state.no+=payload.no;} }, actions:{ increment({commit},info){ setTimeout(function(){ commit('increment',info) },500) } } }) var app = new Vue({ el:"#app", store, computed:{ ...Vuex.mapState(['no']), ...Vuex.mapGetters(['No']) }, methods:{ ...Vuex.mapMutations(['increment']), ...Vuex.mapActions({increment1:"increment"}), test1(){ this.increment({no:100}) }, test2(){ this.increment1({no:200}) } } }) </script></body></html>
writer by:大沙漠 QQ:22969969
我覺得吧,如果用到的vuex里的屬性比較多還好一點,如果只用到一個state還不如用this.$store.state來獲取呢,畢竟在node環境下還需要import{mapState} from 'vuex'來獲取匯出的符號,可以看頁面具體的需求選擇合理的方法,
原始碼分析
vuex內的所有輔助函式格式都一樣,都是執行一個normalizeNamespace()函式,并傳入一個匿名函式,該匿名函式帶有兩個引數,分別是namespace和map,以mapState為例,如下:
var mapState = normalizeNamespace(function (namespace, states) { //state輔助函式 name:命名空間 states:比如:count2: "count" var res = {}; normalizeMap(states).forEach(function (ref) { //將states轉換為物件格式,例如:[{key:count2,val:count}] var key = ref.key; var val = ref.val; res[key] = function mappedState () { //計算屬性對應的是一個函式,該函式內的this指向的是Vue實體 var state = this.$store.state; //獲取state物件 var getters = this.$store.getters; //獲取getters物件 if (namespace) { var module = getModuleByNamespace(this.$store, 'mapState', namespace); if (!module) { return } state = module.context.state; getters = module.context.getters; } return typeof val === 'function' ? val.call(this, state, getters) //state是函式時的邏輯,獲取子模塊的state會執行到這里 : state[val] //回傳state[val],也就是值 }; // mark vuex getter for devtools res[key].vuex = true; }); return res});
normalizeNamespace是統一的一個入口,用于格式化所有的輔助函式,如下:
function normalizeNamespace (fn) { //回傳一個匿名函式,需要兩個引數,分別是命名空間和映射,引數1可以省略 return function (namespace, map) { if (typeof namespace !== 'string') { //如果引數1不是字串(即忽略了命名空間) map = namespace; //則修正引數1為map namespace = ''; //重置命名空間為null } else if (namespace.charAt(namespace.length - 1) !== '/') { namespace += '/'; } return fn(namespace, map) //最后執行fn函式 }}
其它幾個輔助函式都差不多,就是傳給normalizeNamespace的函式內實作略有不同,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/41310.html
標籤:HTML5
