vuex 源码分析(六) 辅助函数 详解
对于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/vue@2.5.16/dist/vue.js"></script> <script src="https://unpkg.com/vuex@3.1.0/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的函数内实现略有不同。
上一篇: Oracle数据库常用的SQL语言命令
下一篇: Android微信九宫格图片展示控件
推荐阅读
-
jQuery 源码分析(四) each函数 $.each和$.fn.each方法 详解
-
vuex 源码分析(七) module和namespaced 详解
-
vuex 源码分析(六) 辅助函数 详解
-
jQuery 源码分析(五) map函数 $.map和$.fn.map函数 详解
-
Vue 2.0 深入源码分析(六) 基础篇 computed 属性详解
-
Hadoop源码分析六启动文件namenode原理详解
-
Vue中之nextTick函数源码分析详解
-
jQuery 源码分析(四) each函数 $.each和$.fn.each方法 详解
-
vuex 源码分析(七) module和namespaced 详解
-
vuex 源码分析(六) 辅助函数 详解