Vuex详解,Web前端开发应该了解的Binder原理

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Web前端全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024c (备注前端)
img

正文

  • State

  • Getters

  • Mutation

  • Action

  • Module

  • 我们对它进行一一介绍.

State单一状态树
  • Vuex提出使用单一状态树, 什么是单一状态树呢?

  • 英文名称是Single Source of Truth,也可以翻译成单一数据源。

  • 但是,它是什么呢?我们来看一个生活中的例子。

  • OK,我用一个生活中的例子做一个简单的类比。

  • 我们知道,在国内我们有很多的信息需要被记录,比如上学时的个人档案,工作后的社保记录,公积金记录,结婚后的婚姻信息,以及其他相关的户口、医疗、文凭、房产记录等等(还有很多信息)。

  • 这些信息被分散在很多地方进行管理,有一天你需要办某个业务时(比如入户某个城市),你会发现你需要到各个对应的工作地点去打印、盖章各种资料信息,最后到一个地方提交证明你的信息无误。

  • 这种保存信息的方案,不仅仅低效,而且不方便管理,以及日后的维护也是一个庞大的工作(需要大量的各个部门的人力来维护,当然国家目前已经在完善我们的这个系统了)。

  • 这个和我们在应用开发中比较类似:

  • 如果你的状态信息是保存到多个Store对象中的,那么之后的管理和维护等等都会变得特别困难。

  • 所以Vuex也使用了单一状态树来管理应用层级的全部状态。

  • 单一状态树能够让我们最直接的方式找到某个状态的片段,而且在之后的维护和调试过程中,也可以非常方便的管理和维护

其核心思想就是不要让数据分布在各个仓库(store)里,而是只用一个store来存储

Getters基本使用

背景:有时候,我们需要从store中获取一些state变异后的状态,比如下面的Store中:

  • 获取学生年龄大于20的个数

const store = new Vuex.Store({

state:{

students:[

{id: 110, name: ‘why’, age: 18},

{id: 111, name: ‘kobe’, age: 24},

{id: 112, name: ‘james’, age: 30},

{id: 113, name: ‘curry’, age: 10}

]

}

})

不用getters时

commputed:{

getGreaterAgeCount(){

return this.$store.state.students.filter(age=> age>=20).length

}

}

在Store中定义getters

getters:{

getGreaterAgeCount:state=>{

return state.students.filter(s=> s.age>=20).length

}

}

如果我们已经有了一个获取所有年龄大于20岁学生列表的getters, 那么代码可以这样来写

//Getters作为参数

getters:{

getGreaterAgeStus:state=>{

return state.students.filter(s=> s.age>=20)

},

getGreaterAgeCount;(state,getters)=>{

return getters.getGreaterAgeStus.length

}

}

getters默认是不能传递参数的, 如果希望传递参数, 那么只能让getters本身返回另一个函数.

  • 比如上面的案例中,我们希望根据ID获取用户的信息

getters:{

/*

这样stuByID返回的就是一个函数fn(),即stuByID()=fn()

而fn有一个形参id,就可以传参数了。那么stuByID(id)=fn(id)

*/

stuByID:state=>{

return function fn(id){

return state.students.find(function fnn(s){

return s.id===id

})

}

}

//简化版

stuByID: state =>id =>state.students.find(s => s.id === id)

}

Mutation状态更新
  • Vuex的store状态的更新唯一方式:提交Mutation

  • Mutation主要包括两部分:

  • 字符串的事件类型(type)

  • 一个回调函数(handler),该回调函数的第一个参数就是state

mutation的定义方式:

mutations:{

//可以定义方法,方法会有一个默认的state参数

increment() {

this.state.counter++

},

//传入一个参数

incrementCount(state,counte) {

state.counter+=counte

},

/*

过mutation更新数据的时候, 有可能我们希望携带一些额外的参数

被称为是mutation的载荷(Payload)

但是如果参数不是一个呢?

我们有很多参数需要传递.

这个时候, 我们通常会以对象的形式传递, 也就是payload是一个对象.

这个时候可以再从对象中取出相关的信息.

*/

//更新多个参数(多个参数打包成一个对象传入)

changeCount(state,payload) {

state.counter+=payload.count

}

}

通过mutation更新

increment(){

this.$store.commit(‘increment’)//字符串对应mutations里面的回调函数

}

incrementCount(counte){

this.$store.commit(‘incrementCount’,counte)//字符串称类型,对应mutations里面的回调函数

}

changeCount(){

this.$store.commit(‘changeCount’,{count:4})

}

Mutation提交风格

上面的通过commit进行提交是一种普通的方式,Vue还提供了另外一种风格, 它是一个包含type属性的对象

在这里插入图片描述

Mutation中的处理方式是将整个commit的对象作为payload使用, 所以代码没有改变, 依然如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wjGZsXOs-1617452300771)(Vuex详解.assets/image-20210403190120766.png)]

mutation的响应规则

传送门

mutation常量类型
概念
  • 我们来考虑下面的问题:

  • 在mutation中, 我们定义了很多事件类型(也就是其中的方法名称).

  • 当我们的项目增大时, Vuex管理的状态越来越多, 需要更新状态的情况越来越多, 那么意味着Mutation中的方法越来越多.

  • 方法过多, 使用者需要花费大量的经历去记住这些方法, 甚至是多个文件间来回切换, 查看方法名称, 甚至如果不是复制的时候, 可能还会出现写错的情况.

  • 如何避免上述的问题呢?

  • 在各种Flux实现中, 一种很常见的方案就是使用常量替代Mutation事件的类型.

  • 我们可以将这些常量放在一个单独的文件中, 方便管理以及让整个app所有的事件类型一目了然.

  • 具体怎么做呢?

  • 我们可以创建一个文件: mutation-types.js, 并且在其中定义我们的常量.

  • 定义常量时, 我们可以使用ES2015中的风格, 使用一个常量来作为函数的名称.

示例

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0tyNylQZ-1617452300772)(Vuex详解.assets/image-20210403193218612.png)]

Mutation同步函数
  • 通常情况下, Vuex要求我们Mutation中的方法必须是同步方法.

  • 主要的原因是当我们使用devtools时, 可以devtools可以帮助我们捕捉mutation的快照.

  • 但是如果是异步操作, 那么devtools将不能很好的追踪这个操作什么时候会被完成.

  • 比如我们之前的代码, 当执行更新时, devtools中会有如下信息:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0dMBdAou-1617452300773)(Vuex详解.assets/image-20210403193520335.png)]

  • 但是, 如果Vuex中的代码, 我们使用了异步函数:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ROxPwDSA-1617452300774)(Vuex详解.assets/image-20210403193547109.png)]

  • 你会发现state中的info数据一直没有被改变, 因为他无法追踪到.

  • So, 通常情况下, 不要再mutation中进行异步的操作

Action
基本定义
  • 我们强调, 不要再Mutation中进行异步操作.

  • 但是某些情况, 我们确实希望在Vuex中进行一些异步操作, 比如网络请求, 必然是异步的. 这个时候怎么处理呢?

  • Action类似于Mutation, 但是是用来代替Mutation进行异步操作的.

  • Action的基本使用代码如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dIvx7BCl-1617452300775)(Vuex详解.assets/image-20210403194018733.png)]

  • context是什么?

  • context是和store对象具有相同方法和属性的对象.

  • 也就是说, 我们可以通过context去进行commit相关的操作, 也可以获取context.state等.

  • 但是注意, 这里它们并不是同一个对象, 为什么呢? 我们后面学习Modules的时候, 再具体说.

  • 这样的代码是否多此一举呢?

  • 我们定义了actions, 然后又在actions中去进行commit, 这不是脱裤放屁吗?

  • 事实上并不是这样, 如果在Vuex中有异步操作, 那么我们就可以在actions中完成了.

Action的分发
  • 在Vue组件中, 如果我们调用action中的方法, 那么就需要使用dispatch

methods:{

increment(){

this.$store.dispatch(‘increment’)

}

}

  • 同样的, 也是支持传递payload

在这里插入图片描述

Action返回的Promise

我们在学ES6语法的时就知道, Promise经常用于异步操作,在Action中, 我们可以将异步操作放在一个Promise中, 并且在成功或者失败后, 调用对应的resolve或reject.

OK, 我们来看下面的代码:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-myXFRr6n-1617452300778)(Vuex详解.assets/image-20210403194746609.png)]

Modules模块

概念:就是在store里面分模块,然后在不同的模块里面再定义state,mutations,actions,getters等等

为什么在Vuex中我们要使用模块呢?
  • Vue使用单一状态树,那么也意味着很多状态都会交给Vuex来管理.

  • 当应用变得非常复杂时,store对象就有可能变得相当臃肿.

  • 为了解决这个问题, Vuex允许我们将store分割成模块(Module), 而每个模块拥有自己的state、mutations、actions、getters等

我们按照什么样的方式来组织模块呢?

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RxXkKNJR-1617452300780)(Vuex详解.assets/image-20210403195412460.png)]

  • 上面的代码中, 我们已经有了整体的组织结构, 下面我们来看看具体的局部模块中的代码如何书写.

  • 我们在moduleA中添加state、mutations、getters

  • mutation和getters接收的第一个参数是局部状态对象

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3ZEoHSrj-1617452300781)(Vuex详解.assets/image-20210403195818918.png)]

  • actions的写法呢? 接收一个context参数对象

  • 局部状态通过 context.state 暴露出来,根节点状态则为 context.rootState

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SiMYnfax-1617452300782)(Vuex详解.assets/image-20210403201636564.png)]

  • 如果getters中也需要使用全局的状态, 可以接受更多的参数

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-comPyAeg-1617452300783)(Vuex详解.assets/image-20210403201659819.png)]

获取不同模块的数据

和写一般的state没有区别,但是注意模块名称。

//是state后面加模块名+数据名,不是模块state再数据名

{{$store.state.modulesA.name}}

不同模块使用mutation

刷面试题

刷题的重要性,不用多说。对于应届生或工作年限不长的人来说,刷面试题一方面能够尽可能地快速自己对某个技术点的理解,另一方面在面试时,有一定几率被问到相同或相似题,另外或多或少也能够为自己面试增加一些自信心,可见适当的刷题是很有必要的。

  • 前端字节跳动真题解析

  • 【269页】前端大厂面试题宝典

最后平时要进行自我分析与评价,做好职业规划,不断摸索,提高自己的编程能力和抽象思维能力。大厂面试远没有我们想的那么困难,摆好心态,做好准备,你也可以的。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024c (备注前端)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
可能地快速自己对某个技术点的理解,另一方面在面试时,有一定几率被问到相同或相似题,另外或多或少也能够为自己面试增加一些自信心,可见适当的刷题是很有必要的。

  • 前端字节跳动真题解析

  • 【269页】前端大厂面试题宝典

最后平时要进行自我分析与评价,做好职业规划,不断摸索,提高自己的编程能力和抽象思维能力。大厂面试远没有我们想的那么困难,摆好心态,做好准备,你也可以的。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024c (备注前端)
[外链图片转存中…(img-msLxZOlf-1713402549358)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值