挑战全网最幽默的Vuex系列教程:第二讲 Vuex旗下的State和Getter
先说两句
上一讲 「Vuex 到底是个什么鬼」,已经完美诠释了 Vuex 的牛逼技能之所在(纯属自嗨)。如果把 Vuex 比喻成农药里面的刘备,那就相当于你现在已经知道了刘备他是一个会打枪的力量型英雄,而且他打的枪还是双排量的,认识到这一点后,那么接下来就是要了解他到底是如何打枪的,是左手打,还是右手打,还是双手一起端着枪打?
同样,我们已经知道了 Vuex 就如同一个全局的管理员一样,帮着我们统一管理着项目的共享数据,那它到底是通过什么样的方式去管理的呢?我们应该如何与这个管理员进行沟通和交流,才能有效的访问和操作这些共享数据呢?
再说一句
Vuex 的内脏由五部分组成:State、Getter、Mutation、Action 和 Module。关于这五个部分,我会分为多个章节来进行详细阐述,这一讲就先和大家一起彻底搞定 State 和 Getter。
当然,在实际应用中,这五个部分并不是必须的,你需要用到什么就添加什么。但是一般再怎么简单的 Vuex,也至少会由 State 和 Mutation 构成,否则你就该考虑 Vuex 是否有存在的必要了。
最后,温馨提示,文档示例代码使用了 ES2015 的语法,如果你还没了解过的话,先戳此了解了解。
单一状态树
Vuex 使用的是「单一状态树」,根据官方的描述,可能有点懵圈,不过没关系,这里我们一起来详细了解下到底什么是「单一状态树」。抛开单一状态,我们先来看一下这里的树是什么意思。
如上图是一个公司的组织架构,它的这种层级其实就属于一种树形的结构,总经理就是树的主干,其他各部门或者职业,都属于树的分支。
一般情况下,一个公司只会有这么一个树形架构,如果有两个平等的总经理,那么公司在管理上很可能就会出现矛盾,下面的人到底听谁的呢,是吧!
好,现在咱们再来看下官方所叙述的「单一状态树」:
1、用一个对象
(主干)
就包含了全部的(分支)
应用层级状态。
2、每个应用(公司)
将仅仅包含一个 store 实例对象(主干)
。单一状态树让我们能够直接地定位任一特定的状态片段,在调试的过程中也能轻易地取得整个当前应用状态的快照。
State
我们再回过头来看一下之前那个简单的 Store 示例代码:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
count: 0
}
})
那么我们如何在 Vue 组件中展示状态呢?由于 Vuex 的状态存储是响应式的,从 store 实例中读取状态最简单的方法就是在计算属性中返回某个状态,如下:
// 创建一个 Counter 组件
const Counter = {
data() { return {} },
template: `<div>{{ count }}</div>`,
computed: {
count () {
return store.state.count
}
}
}
每当
store.state.count
变化的时候, 都会重新求取计算属性,并刷新界面。
需要注意的是,如果你把 store.state.count
放在 data 中, store.state.count
的变化是不会主动触发界面刷新的,当然,也不能直接这样:<div>{{ store.state.count }}</div>
,因为在模板中是无法直接访问到 store 对象的,所以这样写无疑会报错。
这种模式依赖于全局的管理员 store,如果模块多了,意味着每个模块或者页面只要用到了这个 state 里面的数据,都得把 store 引入进来,这样的操作确实有点难受。当然,官方肯定是不允许有这样令人抓狂的操作出现的:
Vuex 通过 store 选项,提供了一种机制将状态从根组件 “注入” 到每一个子组件中(需调用 Vue.use(Vuex)):
const app = new Vue({
el: '#app',
// 把 store 对象提供给 “store” 选项,
// 这可以把 store 的实例注入所有的子组件
store,
// 子组件
components: { Counter },
template: `
<div class="app">
<counter></counter>
</div>
`
})
通过在根实例中注册 store 选项,该 store 实例会注入到根组件下的所有子组件中,且子组件能通过 this.$store 访问到。让我们更新下 Counter 的实现:
const Counter = {
template: `<div>{{ count }}</div>`,
computed: {
count () {
return this.$store.state.count
}
}
}
Vuex 的状态固然好用,但是也不要滥用:
使用 Vuex 并不意味着你需要将所有的状态放入 Vuex。虽然将所有的状态放到 Vuex 会使状态变化更显式和易调试,但也会使代码变得冗长和不直观。如果有些状态严格属于单个组件,最好还是作为组件的局部状态。你应该根据你的应用开发需要进行权衡和确定。
Getter
有时候,我们会发现 State 中的数据,并不是我们直接想要的,而是需要经过相应的处理后,才能满足我们的需求。
比如在一个组件中,我们需要把 state 中的日期 date 转换成星期几来展示:
computed: {
weekDate () {
return moment(this.$store.state.date).format('dddd');
}
}
注意:这里的 moment 是一个第三方日期处理类库,使用之前需要导入。
如果只有一个组件需要这样做还好,但如果在很多组件中,都需要这么转换的话,那就得在每一个组件中都需要把这个函数复制过去。而且,一旦产品经理心情不好,不想用星期几来显示,想直接用 2018-10-30 11:12:23
这种方式来显示日期,那你就得在所有用到它的组件中去更改日期格式化的方法,岂不难受至极。就算你把它单独抽取出来作为一个公共的函数,各种导入也麻烦,最重要的是不好统一管理。
所以,这个时候,Vuex 又引入了一个牛逼的玩意儿,Getter。我们可以把它当成 store 中的计算属性(computed)。
就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
我们看看这两个例子,着重注意下里面的注释:
const store = new Vuex.Store({
state: {
date: new Date()
},
getters: {
// Getter 接受 state 作为其第一个参数
weekDate: state => {
return moment(state.date).format('dddd');
}
}
})
getters: {
// Getter 还也可以接收 getters 作为第二个参数
dateLength: (state, getters) => {
return getters.weekDate.length;
}
}
不但如此,Getter 还会将 store.getters 对象暴露出去,你可以以属性的形式访问这些值:
console.log(store.getters.weekDate)
我们可以很容易地在任何组件中使用它:
computed: {
weekDate () {
return this.$store.getters.weekDate
}
}
现在需求又变了,每个模块要显示的 weekDate 的格式不一样,有的显示全部日期,有的需要显示星期几,怎么办?
好办,那就给 Getter 传参呗,但是怎么传呢?
因为 Getter 在通过属性访问时是作为 Vue 的响应式系统的一部分缓存其中的,所以是不能直接 store.getters.weekDate('MM Do YY')
,因为 weekDate 并不是一个函数,它仅仅只是一个属性而已。
那么既然属性不能传参,怎么办呢?那我们就想办法把这个属性变成一个函数不就行了。
getters: {
// 返回一个函数,就可以传参了
weekDate: (state) => (fm) => {
return moment(state.date).format(fm ? fm : 'dddd');
}
}
使用如下:
store.getters.weekDate('MM Do YY')
写在最后
可能看过官方文档的童鞋会好奇,为什么没有讲解那些辅助函数,比如 mapState
、mapGetters
。别担心,后面会有专门的一个章节来进行讲解,因为我发现这些辅助函数(包括后面的 mapMutations
和 mapActions
)都是为了解决同一个问题而生,只是形式不同罢了,所以还不如拆出来一起讲,或许效果会更好。
对于官方我个人觉得写得比较通俗易懂的地方,就直接引用了进来。如果有疑问或者对于我的理解有疑问的地方,欢迎留言。
当然,这种技术型的文章在不同阶段的人看来,肯定会有不一样的体会。我知道,肯定会有不足的地方,我也会继续慢慢的完善。如果文章对大家有帮助的话,欢迎点赞和转载,谢谢!
转载声明:
作者:大宏说
后记
以上就是胡哥今天给大家分享的内容,喜欢的小伙伴记得点赞
、收藏
呦,关注胡哥有话说,学习前端不迷路,欢迎多多留言交流...
胡哥有话说,一个有技术,有情怀的胡哥!现任京东前端攻城狮一枚。
胡哥有话说,专注于大前端技术领域,分享前端系统架构,框架实现原理,最新最高效的技术实践!
挑战全网最幽默的Vuex系列教程:第二讲 Vuex旗下的State和Getter的更多相关文章
- 挑战全网最幽默的Vuex系列教程:第三讲 Vuex旗下的Mutation
写在前面 上一讲「Vuex 旗下的 State 和 Getter」,告诉了我们怎么去使用仓库 store 中的状态数据.当然,光会用肯定还不够,大部分的应用场景还得对这些状态进行操控,那么具体如何操控 ...
- Spring cloud系列教程第二篇:支付项目父工程图文搭建
Spring cloud系列教程第二篇:支付项目父工程图文搭建 在讲解spring cloud相关的技术的时候,咱们就模拟订单支付这个流程来讲讲 在这个支付模块微服务搭建过程中,上面的这些技术,都会融 ...
- 挑战全网最幽默的Vuex系列教程:第五讲 Vuex的小帮手
先说两句 前面已经讲完了 Vuex 下的 State.Getter.Mutation 及 Action 这四驾马车,不知道大家是否已经理解.当然,要想真正熟练掌握的话,还是需要不断的练习和动手实践才行 ...
- 挑战全网最幽默的Vuex系列教程:第六讲 Vuex的管理员Module(实战篇)
写在前面 这一讲是 Vuex 基础篇的最后一讲,也是最为复杂的一讲.如果按照官方来的话,对于新手可能有点难以接受,所以想了下,决定干脆多花点时间,用一个简单的例子来讲解,顺便也复习一下之前的知识点. ...
- Vue.js 系列教程 4:Vuex
这是关于 JavaScript 框架 Vue.js 五个教程的第四部分.在这一部分,我们会学习使用 Vuex 进行状态管理. 这不是一个完整的指南,而是基础知识的概述,所以你可以了解 Vue.js 以 ...
- Cobalt Strike系列教程第二章:Beacon详解
上周更新了Cobalt Strike系列教程第一章:简介与安装,文章发布后,深受大家的喜爱,遂将该系列教程的其他章节与大家分享,提升更多实用技能! 第二章:Beacon详解 一.Beacon命令 大家 ...
- 挑战全网最幽默的Vuex系列教程:第一讲 Vuex到底是什么鬼
先说两句 官方已经有教程了,为什么还要写这个教程呢?说实话,还真不是我闲着蛋疼,官方的教程真的是太官方了,对于刚入门 Vuex 的童鞋来说,想必看官方的教程,很多地方就如同看圣经一样,比如「欧玛尼玛尼 ...
- CODING 敏捷实战系列课第二讲:Scrum 敏捷项目管理核心要素之 3355
Scrum 是敏捷开发流派中最著名和最落地的一支,全球 70% 以上公司的敏捷转型都是以 Scrum 起步.CODING 特邀敏捷顾问.CST & CTC 认证敏捷教练申健老师将在本课程< ...
- Smart3D系列教程2之 《为什么三维重建效果这么差?——探探那些被忽略的拍照要求和技巧》
一.照片采集的实用概念 根据照片进行三维重建的过程中,有人没怎么遇到坑,有人被坑的不轻.可能是模型的纹理失真,模型的法线错了,模型会生成我们各种也想不到的结果,那么,是什么导致三维重建效果这么差的?是 ...
随机推荐
- System.Text.Json 序列化对所有 JSON 属性名称使用 camel 大小写
asp.net core3.x 新增的序列号接口System.Text.Json 序列化时,如果要对所有 JSON 属性名称使用 camel 大小写 将 JsonSerializerOptions.P ...
- Unity 游戏框架:资源管理神器 ResKit
此篇文章准备了将近两周的时间,写了改,改了删.之前有朋友反馈,上一个文章太冗长了,影响阅读体验,这一讲就走个精简路线.所以只要不是很重要的内容就都删减掉了. 文章分两个部分,第一部分是原理,第二部分是 ...
- android studio 导入RecyclerView
- 记录一次线上bug
记录一次线上bug,总的来说就是弱网和重复点击.特殊值校验的问题. 测试场景一: 在3g网络或者使页面加载速度需要两秒左右的时候,输入学号,提交学生的缴费项目,提交完一个 学生的缴费后, ...
- 《HelloGitHub》第 48 期
兴趣是最好的老师,HelloGitHub 就是帮你找到兴趣! 简介 分享 GitHub 上有趣.入门级的开源项目. 这是一个面向编程新手.热爱编程.对开源社区感兴趣 人群的月刊,月刊的内容包括:各种编 ...
- linux-manjaro下添加Yahei Hybrid Consola字体
1.下载地址 http://www.win10zhijia.net/soft/20160921/3217.html 2.解压 unzip xxx 3.安装 sudo mkdir /usr/share/ ...
- 干货|漫画算法:LRU从实现到应用层层剖析(第一讲)
今天为大家分享很出名的LRU算法,第一讲共包括4节. LRU概述 LRU使用 LRU实现 Redis近LRU概述 第一部分:LRU概述 LRU是Least Recently Used的缩写,译为最近最 ...
- tensorflow 控制流操作,条件判断和循环操作
Control flow operations: conditionals and loops When building complex models such as recurrent neura ...
- Java生鲜电商平台-电商中"再来一单"功能架构与详细设计(APP/小程序)
Java生鲜电商平台-电商中"再来一单"功能架构与详细设计(APP/小程序) 说明:在实际的业务场景中(无论是TO B还是TO C)不管是休闲食品.餐饮.水果.日用百货.母婴等高频 ...
- 如何有效的阅读JDK源码
阅读Java源码的前提条件: 1.技术基础 在阅读源码之前,我们要有一定程度的技术基础的支持. 假如你从来都没有学过Java,也没有其它编程语言的基础,上来就啃<Core Java>,那样 ...