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 ...
随机推荐
- NOI2018 网络同步赛的启示
D1D2一共6题,暴露出我的许多问题 D1 T1 100 T2 8 T3 0 D2 T1 90? T2 15? T3 0 D1T1:决不能在noip之后便不再写dijkstra 不再写kruskal和 ...
- python selenium chrome有界面与无界面模式
from selenium.webdriver.chrome.options import Options from selenium import webdriver # 无界面模式 def Chr ...
- 过滤特殊字符(包括过滤emoji表情)
/** * 过滤特殊字符 * @param $text * @return mixed */ public static function filterSpecialChars($text) { // ...
- 前端诡异参数start
今天搞了一下午只为一个诡异事件:前端请求数据时总是会传一个start=20的参数,二搜索整个项目也找不出这个start的踪影. 倒是搜到一个pageLength的参数是20,但就是找不到start. ...
- squid代理服务器安装和配置
服务器版本:centos6.5 squid版本:3.1 Squid介绍 Squid是一个缓存Internet 数据的软件,其接收用户的下载申请,并自动处理所下载的数据.当一个用户想要下载一个主页时,可 ...
- 大R玩家体验时空猎人折扣平台多角度分析
<时空猎人>讲述了时空裂隙的出现,导致大批魔物入侵阿达拉大陆.玩家可扮演狼人.机械师.异能者.冰魄等职业,与这片大陆的人们保卫家园. 游戏拥有宠物.等战斗培养元素,还引入竞技场.攻城战等P ...
- Install Virtualbox on ubuntu
1.Use the command: sudo apt-get install virtualbox
- default activity not found的问题
莫名其妙的同一个project下的所有modlue全都出现了这个问题,在网上查了一些解决方法,总结一下就是在运行时把default activity改成nothing,这个把活动都搞没了肯定不行.还有 ...
- Codeforces 946 D.Timetable-数据处理+动态规划(分组背包) 处理炸裂
花了两个晚上来搞这道题. 第一个晚上想思路和写代码,第二个晚上调试. 然而还是菜,一直调不对,我的队友是Debug小能手呀(真的是无敌,哈哈,两个人一会就改好了) D. Timetable tim ...
- linux--磁盘及文件系统管理
磁盘管理 : 主流的磁盘 : 机械式硬盘 常见的有 : U盘, 光盘, 软盘, 硬盘, 磁带机 扇区 : sector 磁道 : track 柱面 : cylinder 磁盘出厂时 : 低级格式化 : ...