对于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的函数内实现略有不同。

vuex 源码分析(六) 辅助函数 详解的更多相关文章

  1. vuex 源码分析(五) action 详解

    action类似于mutation,不同的是Action提交的是mutation,而不是直接变更状态,而且action里可以包含任意异步操作,每个mutation的参数1是一个对象,可以包含如下六个属 ...

  2. 【集合框架】JDK1.8源码分析之ArrayList详解(一)

    [集合框架]JDK1.8源码分析之ArrayList详解(一) 一. 从ArrayList字表面推测 ArrayList类的命名是由Array和List单词组合而成,Array的中文意思是数组,Lis ...

  3. nginx源码分析线程池详解

    nginx源码分析线程池详解 一.前言     nginx是采用多进程模型,master和worker之间主要通过pipe管道的方式进行通信,多进程的优势就在于各个进程互不影响.但是经常会有人问道,n ...

  4. vuex 源码解析(四) mutation 详解

    mutation是更改Vuex的store中的状态的唯一方法,mutation类似于事件注册,每个mutation都可以带两个参数,如下: state ;当前命名空间对应的state payload ...

  5. Golang源码分析之目录详解

    开源项目「go home」聚焦Go语言技术栈与面试题,以协助Gopher登上更大的舞台,欢迎go home~ 导读 学习Go语言源码的第一步就是了解先了解它的目录结构,你对它的源码目录了解多少呢? 目 ...

  6. Tomcat源码分析 | 一文详解生命周期机制Lifecycle

    目录 什么是Lifecycle? Lifecycle方法 LifecycleBase 增加.删除和获取监听器 init() start() stop() destroy() 模板方法 总结 前言 To ...

  7. Java 容器源码分析之集合类详解

    集合类说明及区别 Collection ├List │├LinkedList │├ArrayList │└Vector │ └Stack └Set Map ├Hashtable ├HashMap └W ...

  8. Cloudera Impala源码分析: SimpleScheduler调度策略详解包括作用、接口及实现等

    问题导读:1.Scheduler任务中Distributed Plan.Scan Range是什么?2.Scheduler基本接口有哪些?3.QuerySchedule这个类如何理解?4.Simple ...

  9. VueX源码分析(5)

    VueX源码分析(5) 最终也是最重要的store.js,该文件主要涉及的内容如下: Store类 genericSubscribe函数 resetStore函数 resetStoreVM函数 ins ...

随机推荐

  1. Node 之 Express 4x 骨架详解

    周末,没事就来公司加班继续研究一下Express ,这也许也是单身狗的生活吧. 1.目录结构: bin, 存放启动项目的脚本文件 node_modules, 项目所有依赖的库,以及存放 package ...

  2. Chapter 2 :重构的原则

    1,什么是重构? 在不改变软件可观察行为的前提下,使用一些重构的手法,提高代码可读性. 换句话说,在保持软件可用的前提下,修改代码使得更加容易被理解. 2,为什么重构? 为了后续的代码维护和修改,易读 ...

  3. python处理sqlserver数据库的返回数据

    上代码: import SqlHelper.MSSQL as MS import pandas as pd if __name__ == '__main__': #连接数据库 ms = MS.MSSQ ...

  4. WeTest全球化服务,为使命召唤手游质量保驾护航

    导读 使命召唤系列作为经典FPS游戏,以良好的表现与出色的射击手感,颠覆了玩家对传统第一人称射击的传统观念.同名手游(CODM)10月份在海外上线,仅一周内下载量就已突破一亿次,更是横扫139个国家及 ...

  5. grep命令提示"binary file matches **.log"解决方法

    仔细想想,这个问题遇到很多次了,之前一直以为很复杂,一搜索发现解决这么简单,记录一下做备忘. grep test XXX.log Binary file app.log matches 此时使用-a参 ...

  6. ThinkPHP 3.2,配置 'URL_MODEL'=>2。 APP_DEBUG设为false,U函数生成的URL的index.php不能去掉,只有将APP_DEBUG改成true,才能去掉index.php,求解~~

    ThinkPHP 3.2,配置 'URL_MODEL'=>2.APP_DEBUG设为false,U函数生成的URL的index.php不能去掉,只有将APP_DEBUG改成true,才能去掉in ...

  7. Flask 安装环境(虚拟环境安装)

    Flask 安装环境 使用虚拟环境安装Flask,可以避免包的混乱和冲突,虚拟环境是python解释器的副本,在虚拟环境中你可以安装扩展包,为每个程序 单独创建虚拟环境,可以保证程序只能访问虚拟环境中 ...

  8. Ubuntu18.04安装Cuda10.1

    注:如果使用anaconda,貌似不需要手动安装Cuda和cudnn,安装tensorflow时会自动安装 1.官方教程https://docs.nvidia.com/cuda/cuda-instal ...

  9. [Linux] 纯净ubuntu快速搭建宝塔面板

    宝塔官方建议是纯净的系统,我使用docker运行一个ubuntu容器,模拟一个纯净的系统,这样也不会影响到我的其他服务. docker run --name baota -id -p 8888:888 ...

  10. 安全类和远程类shell脚本

    批量杀php小马脚本 find /home/hatdot/ -name "*.php" |xargs egrep "phpspy|c99sh|milw0rm|eval\( ...