vuex 源码:深入 vuex 之辅助函数 mapState
前言
当一个组件要获取多个 state 的时候,声明计算属性就会变得重复和冗余了。我们可以使用到辅助函数 mapState 来更快更简洁地生成计算属性。
所以我们得清楚,mapState 的作用就是帮我们把一个对象或数组里的值转化成计算属性的写法。同理,其它的辅助函数也是大同小异,只要知道了 mapState 的实现,其它的也基本都明白了。
注:本次阅读的是 vuex 的 2.0.0 版本,源码请戳 这里。
准备
解读前,我们需要熟悉一些方法的使用:
解读
先来 mapState 的使用方式:
import { mapState } from 'vuex'
export default {
computed: mapState([
// 映射 this.count 为 store.state.count
'count'
])
}
mapState 返回一个对象,我们知道以上的代码最后会变成这样:
import { mapState } from 'vuex'
export default {
computed: {
count () {
return this.$store.state.count
}
}
}
那么我们就来开始看看 mapState 做了什么处理。
还是从 vuex 的 APi 看起,打开 src/index.js 文件,最下面的代码中可以看到 vuex 暴露出的 mapState:
export default {
Store,
install,
mapState,
mapMutations,
mapGetters,
mapActions
}
定位后可以找到最前面的引入:
import { mapState, mapMutations, mapGetters, mapActions } from './helpers'
打开 src/helpers.js
文件,里面便有 mapState 的实现。
normalizeMap
想知道 mapStat 这个方法的实现,还得知道里面的 normalizeMap
这个方法的实现。定位找到 normalizeMap
方法:
function normalizeMap (map) {
return Array.isArray(map)
? map.map(key => ({ key, val: key }))
: Object.keys(map).map(key => ({ key, val: map[key] }))
}
这个方法主要是格式化 mapState 传进来的 states 参数。我们会知道 states 参数会是两种形式,一种是以数组的方式传入,另一种则是以对象的方法传入。
例如以下代码:
// 以数组的方式传入
mapState([
'count',
'add'
])
// 以对象的方法传入
mapState({
count: state => state.count,
countAlias: 'count'
})
经过 normalizeMap
方法处理后会变成这样:
// 以数组的方式传入
[
{
key: 'count',
val: 'count'
},
{
key: 'add',
val: 'add'
}
]
// 以对象的方法传入
[
{
key: count,
val: state => state.count
},
{
key: countAlias,
val: 'count'
}
]
mapState
知道了 normalizeMap
方法的实现,再回头看 mapState
方法的实现:
export function mapState (states) {
const res = {}
normalizeMap(states).forEach(({ key, val }) => {
res[key] = function mappedState () {
return typeof val === 'function'
? val.call(this, this.$store.state, this.$store.getters)
: this.$store.state[val]
}
})
return res
}
对刚刚 normalizeMap 格式化后返回的数组进行遍历,拼接一个符合 computed 的对象(需有返回值)。
对 normalizeMap 返回数组的对象里的 val 有两个判断。如果不是函数,直接查找 this.$store.state[val]
返回 state。如果是函数,则需要使用 call 将 val 这个函数的 this 指向 vue 实例,然后将 state 和 getters 传入,最后执行 val 函数。
val 函数
如果 val 是函数,可能有点难理解,举个例子,传入的参数可能是这样子的:
computed: mapState({
countPlusLocalState (state) {
return state.count + this.localCount
}
})
经过 normalizeMap
方法后返回的对象为:
[
{
key: 'countPlusLocalState',
val: function (state) {
return state.count + this.localCount
}
}
]
再经过 mapState 最后返回的 res 是。这里会将 val 函数执行一遍,将函数的返回值 return 出来。
{
countPlusLocalState: function mappedState () {
return this.$store.state.count + this.localCount
}
}
至此,mapState 的解读已经结束了。另外,mapState 还经常使用到 es6 的扩展运算符,这个不是 vuex 的实现,而是 es6 的一个新特性:
computed: {
localComputed () { /* ... */ },
// 使用对象展开运算符将此对象混入到外部对象中
...mapState({
// ...
})
}
例外需要注意,如果要使用 es6 的扩展运算符,还需要引入一个 babel 包:babel-plugin-transform-object-rest-spread。
总结
mapState 的代码不多,主要的功能就是将传入的数组或对象转成 computed 计算属性能够识别的代码。比较难理解的就是对象带有函数的返回值有点绕,多看几遍理解理解。
mapState 里面的代码实现非常的简洁精湛,主要用到了 js 的一些内置函数做处理,如果是我,估计会一直写 for 循环实现吧哈哈,从中收获到不少知识的。至此,vuex 的解读算告一段落。
vuex 源码:深入 vuex 之辅助函数 mapState的更多相关文章
- vuex 源码分析(六) 辅助函数 详解
对于state.getter.mutation.action来说,如果每次使用的时候都用this.$store.state.this.$store.getter等引用,会比较麻烦,代码也重复和冗余,我 ...
- VueX源码分析(2)
VueX源码分析(2) 剩余内容 /module /plugins helpers.js store.js helpers要从底部开始分析比较好.也即先从辅助函数开始再分析那4个map函数mapSta ...
- VueX源码分析(5)
VueX源码分析(5) 最终也是最重要的store.js,该文件主要涉及的内容如下: Store类 genericSubscribe函数 resetStore函数 resetStoreVM函数 ins ...
- VueX源码分析(4)
VueX源码分析(4) /module store.js /module/module.js import { forEachValue } from '../util' // Base data s ...
- VueX源码分析(1)
VueX源码分析(1) 文件架构如下 /module /plugins helpers.js index.esm.js index.js store.js util.js util.js 先从最简单的 ...
- 逐行粒度的vuex源码分析
vuex源码分析 了解vuex 什么是vuex vuex是一个为vue进行统一状态管理的状态管理器,主要分为state, getters, mutations, actions几个部分,vue组件基于 ...
- Vuex 源码学习(一)
(一)Vuex 是什么? Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态, 并以相应的规则保证状态以一种可预测的方式发生变化. —— 来自 V ...
- vuex源码 安装依赖问题
今天下载vuex源码时 安装依赖出现以下问题 > chromedriver@2.32.3 install /Users/bao/Desktop/vue-store/vuex/node_modul ...
- VueX源码分析(3)
VueX源码分析(3) 还剩余 /module /plugins store.js /plugins/devtool.js const devtoolHook = typeof window !== ...
- 一张思维导图辅助你深入了解 Vue | Vue-Router | Vuex 源码架构
1.前言 本文内容讲解的内容:一张思维导图辅助你深入了解 Vue | Vue-Router | Vuex 源码架构. 项目地址:https://github.com/biaochenxuying/vu ...
随机推荐
- Percona Server 5.6 安装TokuDB
系统:Red Hat Enterprise Linux Server release 6.3 (Santiago) 数据库:Percona-Server-5.6.29-rel76.2-Linux.x8 ...
- 12: xlrd 处理Excel文件
1.1 xlrd处理.xlsx 文件 1.xlrd常用方法 #!/usr/bin/python # coding:utf-8 # 用xlrd读取Excel文件基本用法 import sys impor ...
- shell 变量相关的命令
变量="变量" readonly 变量名="变量" 表示设置该变量为只读变量 ,这个变量不能别改变 echo $变量名 set 显示本地所有的变量 unse ...
- CentOS7使用命令连接网络配置
背景 在安装完CentOS7无桌面的情况下,无法使用桌面图标连接,如下图所示,这时我们需要在配置文件中配置网络连接信息. 步骤 查看ip地址:ifconfig PS:在未连接网络之前,我们是查看不到i ...
- 嵌入式电路中的BUCK VS LDO【转】
本文转载自:http://blog.chinaunix.net/uid-25906157-id-4125916.html 作为一名FAE,才知硬件知识的匮乏.慢慢积累一点儿硬件知识吧!BUCK和LDO ...
- newcoder H肥猪(单调队列 / 线段树)题解
题意: 小B来到了一个异世界,成为了肥猪之王. 在这个异世界,共有n种肥猪,编号分别为1,...,n. 小B希望集齐这n种肥猪. 召集肥猪有两种方式: 1. 花费a[i]的金币召唤一只编号为i的肥猪. ...
- FJUT3574 HOME_W的附加题(带权线段树)题解
题意: 给定n个数a1,a2,a3,……an.和m次操作. 每次操作格式如下 x y k 表示将a[x]替换为y.并求替换后,前k小的数之和 思路:我们用带权线段树维护权值,这里就是维护i的个数n ...
- 程序重启RocketMQ消息重复消费
最近在调试RocketMQ消息发送与消费的Demo时,发现一个问题:只要重启程序,RocketMQ消息就会重复消费. 那么这是什么原因导致的,又该如何解决呢? 经过一番排查,发现程序使用的Rocket ...
- c# 之系统环境安装
在重装系统后,对一些原有软件进行了卸载,不知道是什么原因总是提示vs2015 需安装IE10,但是又碰到ie10的一些插件不适合此系统.网上介绍的vs修复没有任何作用 最后找到方法是:重装系统,然后不 ...
- $on在构造器外部添加事件(通过$emit进行外部调用)$once执行一次的事件(通过$emit进行外部调用)$off关闭事件
$on 在构造器外部添加事件. $on接收两个参数,第一个参数是调用时的事件名称,第二个参数是一个匿名方法. 如果按钮在作用域外部,可以利用$emit来执行. html <div id=&quo ...