vuex的工作原理

article/2025/4/22 10:41:17

Vuex是做什么的?

官方解释:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。

  • 它采用 集中式存储管理 应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
  • Vuex 也集成到 Vue 的官方调试工具 devtools extension,提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。

状态管理到底是什么?

  • 状态管理模式、集中式存储管理这些名词听起来就非常高大上,让人捉摸不透。
  • 其实,你可以简单的将其看成把需要多个组件共享的变量全部存储在一个对象里面。
  • 然后,将这个对象放在顶层的Vue实例中,让其他组件可以使用。
  • 那么,多个组件是不是就可以共享这个对象中的所有变量属性了呢?

等等,如果是这样的话,为什么官方还要专门出一个插件Vuex呢?难道我们不能自己封装一个对象来管理吗?
举个例子:

const shareobj={
name:'why
}
Vue.prototype.shareobj shareobjvue.component('cpn1',this.shareobj.name
})
Vue.component('cpn2',{})

这个时候界面上就可以展示这个name了,但是这样做不好,原因是他不是响应式的,我们将name从‘why’变成’kobe’,界面上的name的值是不会发生变化的,

  • 当然可以,只是我们要先想想VueJS带给我们最大的便利是什么呢?没错,就是响应式。
  • 如果你自己封装实现一个对象能不能保证它里面所有的属性做到响应式呢?当然也可以,只是自己封装可能稍微麻烦一些。
  • 不用怀疑,Vuex就是为了提供这样一个在多个组件间共享状态的插件,用它就可以了。

管理什么状态呢?

有什么状态时需要我们在多个组件间共享的呢?

  • 如果你做过大型开放,你一定遇到过多个状态,在多个界面间的共享问题。
  • 比如用户的登录状态、用户名称、头像、地理位置信息等等。
  • 比如商品的收藏、购物车中的物品等等。
    这些状态信息,我们都可以放在统一的地方,对它进行保存和管理,而且它们还是响应式的

单界面的状态管理

在这里插入图片描述

  • State:不用多说,就是我们的状态。
  • View:视图层,可以针对State的变化,显示不同的信息。
  • Actions:这里的Actions主要是用户的各种操作:点击、输入等等,会导致状态的改变。
    在这里插入图片描述
    在这个案例中,我们有没有状态需要管理呢?没错,就是个数counter。
    counter需要某种方式被记录下来,也就是我们的State。
    counter目前的值需要被显示在界面中,也就是我们的View部分。
    界面发生某些操作时(我们这里是用户的点击,也可以是用户的input),需要去更新状态,也就是我们的Actions
    这不就是上面的流程图了吗?

多界面状态管理

  • Vue已经帮我们做好了单个界面的状态管理,但是如果是多个界面呢?
    • 多个视图都依赖同一个状态(一个状态改了,多个界面需要进行更新)
    • 不同界面的Actions都想修改同一个状态(Home.vue需要修改,Profile.vue也需要修改这个状态)
  • 也就是说对于某些状态(状态1/状态2/状态3)来说只属于我们某一个视图,但是也有一些状态(状态a/状态b/状态c)属于多个试图共同想要维护的
    • 状态1/状态2/状态3你放在自己的房间中,你自己管理自己用,没问题。
    • 但是状态a/状态b/状态c我们希望交给一个大管家来统一帮助我们管理!!!
    • 没错,Vuex就是为我们提供这个大管家的工具。
  • 全局单例模式(大管家)
    • 我们现在要做的就是将共享的状态抽取出来,交给我们的大管家,统一进行管理。
    • 之后,你们每个视图,按照我规定好的规定,进行访问和修改等操作。
    • 这就是Vuex背后的基本思想

Vuex状态管理图例

在这里插入图片描述
每一个 Vuex 应用的核心就是 store,里面又包括:
(1)state(数据):用来存放数据源,就是公共状态;
(2)getters(数据加工):有的时候需要对数据源进行加工,返回需要的数据;
(3)actions(事件):要执行的操作,可以进行同步或者异步事件
(4)mutations(执行):操作结束之后,actions通过commit更新state数据源(同步操作)
(5)modules:使用单一状态树,致使应用的全部状态集中到一个很大的对象,所以把每个模块的局部状态分装使每一个模块拥有本身的 state、mutation、action、getters、甚至是嵌套子模块;

vuex的工作流程就是:
(1)通过dispatch去提交一个actions,
(2) actions接收到这个事件之后,在actions中可以执行一些异步|同步操作,根据不同的情况去分发给不同的mutations,
(3)actions通过commit去触发mutations,
(4)mutations去更新state数据,state更新之后,就会通知vue进行渲染

devtools插件作用:跟踪记录每一次改变state的状态,从而知道是哪个组件修改了state (前提:state是通过mutations修改)(只能跟踪同步操作)

为什么Vuex要通过mutations修改state,而不能直接修改?

因为state是实时更新的,mutations无法进行异步操作,而如果直接修改state的话是能够异步操作的,当你异步对state进行操作时,还没执行完,这时候如果state已经在其他地方被修改了,这样就会导致程序存在问题了。所以state要同步操作,通过mutations的方式限制了不允许异步。
另外我们还用到了devtools这个工具,如果直接修改state的话,它是没有办法跟踪的,而vue提供这个工具是为了帮助我们在多个界面都来修改state,它希望做一个跟踪,这时当某一个界面修改这个state修改错误它就可以跟踪到是哪里修改错了,再做相关的调试。更加方便。

devtools的安装与使用

在chrome浏览器的网上应用商城中
在这里插入图片描述
同步到扩展程序中,之后关闭浏览器以后重新打开。
在这里插入图片描述
简单的案例:
首先,我们需要在某个地方存放我们的Vuex代码:
这里,我们先创建一个文件夹store,并且在其中创建一个index.js文件
在index.js文件中写入如下代码:

在这里插入图片描述
其次,我们让所有的Vue组件都可以使用这个store对象
来到main.js文件,导入store对象,并且放在new Vue中
这样,在其他Vue组件中,我们就可以通过this.$store的方式,获取到这个store对象了
在这里插入图片描述

我们来对使用步骤,做一个简单的小节:
1.提取出一个公共的store对象,用于保存在多个组件中共享的状态
2.将store对象放置在new Vue对象中,这样可以保证在所有的组件中都可以使用到
3.在其他组件中使用store对象中保存的状态即可
通过this.$ store.state.属性的方式来访问状态
通过this.$ store.commit(‘mutation中方法’)来修改状态
注意事项:
我们通过提交mutation的方式,而非直接改变store.state.count。
这是因为Vuex可以更明确的追踪状态的变化,所以不要直接改变store.state.count的值。

在这里插入图片描述

Vuex核心概念

  • State
    Vuex提出使用单一状态树, 什么是单一状态树呢?
    英文名称是Single Source of Truth,也可以翻译成单一数据源。
    但是,它是什么呢?我们来看一个生活中的例子。
    我们知道,在国内我们有很多的信息需要被记录,比如上学时的个人档案,工作后的社保记录,公积金记录,结婚后的婚姻信息,以及其他相关的户口、医疗、文凭、房产记录等等(还有很多信息)。
    这些信息被分散在很多地方进行管理,有一天你需要办某个业务时(比如入户某个城市),你会发现你需要到各个对应的工作地点去打印、盖章各种资料信息,最后到一个地方提交证明你的信息无误。
    这种保存信息的方案,不仅仅低效,而且不方便管理,以及日后的维护也是一个庞大的工作(需要大量的各个部门的人力来维护,当然国家目前已经在完善我们的这个系统了)。
    这个和我们在应用开发中比较类似:
    如果你的状态信息是保存到多个Store对象中的,那么之后的管理和维护等等都会变得特别困难。
    所以Vuex也使用了单一状态树来管理应用层级的全部状态。
    单一状态树能够让我们最直接的方式找到某个状态的片段,而且在之后的维护和调试过程中,也可以非常方便的管理和维护。

  • Getters
    它类似我们单个组件中的计算属性,计算属性一般在什么时候使用呢?当我们的某一个数据必须经过一系列的变换的时候。那Getter也是这样,比如说想要从state中获取某个counter,每次在很多地方获取counter以后想要获取counter的平方,也就是counter要经过某种变换以后,再给用户返回回来。这个时候就可以使用getters
    有时候,我们需要从store中获取一些state变异后的状态,比如下面的Store中:
    获取学生年龄大于20的个数。
    在这里插入图片描述
    我们可以在Store中定义getters

在这里插入图片描述
在这里插入图片描述Getters作为参数和传递参数
如果我们已经有了一个获取所有年龄大于20岁学生列表的getters, 那么代码可以这样来写
在这里插入图片描述
getters默认是不能传递参数的, 如果希望传递参数, 那么只能让getters本身返回另一个函数.
比如上面的案例中,我们希望根据ID获取用户的信息
在这里插入图片描述

  • Mutation
    Vuex的store状态的更新唯一方式:提交Mutation
    Mutation主要包括两部分:
    字符串的事件类型(type)
    一个回调函数(handler),该回调函数的第一个参数就是state。
    mutation的定义方式:
    在这里插入图片描述
    通过mutation更新
    在这里插入图片描述
    在通过mutation更新数据的时候, 有可能我们希望携带一些额外的参数
    参数被称为是mutation的载荷(Payload)
    Mutation中的代码:
    在这里插入图片描述
    但是如果参数不是一个呢?
    比如我们有很多参数需要传递.
    这个时候, 我们通常会以对象的形式传递, 也就是payload是一个对象.
    这个时候可以再从对象中取出相关的信息.
    在这里插入图片描述
    上面的通过commit进行提交是一种普通的方式
    Vue还提供了另外一种风格, 它是一个包含type属性的对象
    在这里插入图片描述Mutation中的处理方式是将整个commit的对象作为payload使用, 所以代码没有改变, 依然如下:

在这里插入图片描述Vuex的store中的state是响应式的, 当state中的数据发生改变时, Vue组件会自动更新.
这就要求我们必须遵守一些Vuex对应的规则:
提前在store中初始化好所需的属性.
当给state中的对象添加新属性时, 使用下面的方式:
方式一: 使用Vue.set(obj, ‘newProp’, 123)
方式二: 用新对象给旧对象重新赋值
我们来看一个例子:
当我们点击更新信息时, 界面并没有发生对应改变.
如何才能让它改变呢?
查看下面代码的方式一和方式二
都可以让state中的属性是响应式的.
在这里插入图片描述
在这里插入图片描述
Mutation常量类型 – 概念
我们来考虑下面的问题:
在mutation中, 我们定义了很多事件类型(也就是其中的方法名称).
当我们的项目增大时, Vuex管理的状态越来越多, 需要更新状态的情况越来越多, 那么意味着Mutation中的方法越来越多.
方法过多, 使用者需要花费大量的经历去记住这些方法, 甚至是多个文件间来回切换, 查看方法名称, 甚至如果不是复制的时候, 可能还会出现写错的情况.
如何避免上述的问题呢?
在各种Flux实现中, 一种很常见的方案就是使用常量替代Mutation事件的类型.
我们可以将这些常量放在一个单独的文件中, 方便管理以及让整个app所有的事件类型一目了然.
具体怎么做呢?
我们可以创建一个文件: mutation-types.js, 并且在其中定义我们的常量.
定义常量时, 我们可以使用ES2015中的风格, 使用一个常量来作为函数的名称.

Mutation同步函数
通常情况下, Vuex要求我们Mutation中的方法必须是同步方法.
主要的原因是当我们使用devtools时, 可以devtools可以帮助我们捕捉mutation的快照.

但是如果是异步操作, 那么devtools将不能很好的追踪这个操作什么时候会被完成.
比如我们之前的代码, 当执行更新时, devtools中会有如下信息:
在这里插入图片描述
但是, 如果Vuex中的代码, 我们使用了异步函数
在这里插入图片描述
你会发现state中的info数据一直没有被改变, 因为他无法追踪到.
So, 通常情况下, 不要再mutation中进行异步的操作

  • Action
    我们强调, 不要再Mutation中进行异步操作.
    但是某些情况, 我们确实希望在Vuex中进行一些异步操作, 比如网络请求, 必然是异步的. 这个时候怎么处理呢?
    Action类似于Mutation, 但是是用来代替Mutation进行异步操作的.
    Action的基本使用代码如下:
    context是什么?
    context是和store对象具有相同方法和属性的对象.
    也就是说, 我们可以通过context去进行commit相关的操作, 也可以获取context.state等.
    但是注意, 这里它们并不是同一个对象, 为什么呢? 我们后面学习Modules的时候, 再具体说.
    这样的代码是否多此一举呢?
    我们定义了actions, 然后又在actions中去进行commit, 这不是多此一举吗?
    事实上并不是这样, 如果在Vuex中有异步操作, 那么我们就可以在actions中完成了.
    在这里插入图片描述在Vue组件中, 如果我们调用action中的方法, 那么就需要使用dispatch
    在这里插入图片描述
    同样的, 也是支持传递payload
    在这里插入图片描述
    Action返回的Promise

前面我们学习ES6语法的时候说过, Promise经常用于异步操作.
在Action中, 我们可以将异步操作放在一个Promise中, 并且在成功或者失败后, 调用对应的resolve或reject.
OK, 我们来看下面的代码:
在这里插入图片描述
在这里插入图片描述

  • Module
    Module是模块的意思, 为什么在Vuex中我们要使用模块呢?
    Vue使用单一状态树,那么也意味着很多状态都会交给Vuex来管理.
    当应用变得非常复杂时,store对象就有可能变得相当臃肿.
    为了解决这个问题, Vuex允许我们将store分割成模块(Module), 而每个模块拥有自己的state、mutation、action、getters等

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

在这里插入图片描述
Module局部状态
上面的代码中, 我们已经有了整体的组织结构, 下面我们来看看具体的局部模块中的代码如何书写.
我们在moduleA中添加state、mutations、getters
mutation和getters接收的第一个参数是局部状态对象
在这里插入图片描述
在这里插入图片描述
注意:
虽然, 我们的doubleCount和increment都是定义在对象内部的.
但是在调用的时候, 依然是通过this.$store来直接调用的.

项目结构

当我们的Vuex帮助我们管理过多的内容时, 好的项目结构可以让我们的代码更加清晰.
在这里插入图片描述

常见的vuex的面试题

Vuex常见面试题大全汇总
VUE之VUEX常见面试题

mutation中 为什么不能进行异步操作?

答:因为当 mutation 触发的时候,回调函数还没有被调用,devtools不知道什么时候回调函数实际上被调用——实质上任何在回调函数中进行的状态的改变都是不可追踪的。如果mutation支持异步操作,就没有办法知道状态是何时更新的,无法很好的进行状态的追踪,给调试带来困难。

Action 通常是异步的,那么 action 什么时候结束呢?

利用 async / await (opens new window),我们可以如下组合 action

// 假设 getData() 和 getOtherData() 返回的是 Promiseactions: {async actionA ({ commit }) {commit('gotData', await getData())},async actionB ({ dispatch, commit }) {await dispatch('actionA') // 等待 actionA 完成commit('gotOtherData', await getOtherData())}
}

一个 store.dispatch 在不同模块中可以触发多个 action 函数。在这种情况下,只有当所有触发函数完成后,返回的 Promise 才会执行。

刷新浏览器后,Vuex的数据是否存在?如何解决?

vuex的数据在刷新浏览器后不会保存,这是因为vuex实例store里的数据保存在运行内存中,页面刷新会重载vue实例,导致store里的数据丢失。
如何解决vuex页面刷新数据丢失问题?


http://chatgpt.dhexx.cn/article/K4FwTxJB.shtml

相关文章

vuex 的实现原理

一、Vuex是什么   Vuex是专门为Vuejs应用程序设计的状态管理工具。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。 1、Vuex的构成 由上图,我们可以看出Vuex有以下几个部分构成: 1&#x…

vuex原理

目录 一、 为啥会出现vuex 二 、什么是vuex 三、 怎么使用vuex 四、vue和vuex比较 五、vuex的五个属性 5.1 state 5.2 mutations 5.3 getters 5.4 Actions 5.5 Modules 六、为啥state里的数据可以实现响应式 七、为啥每个组件都可以拿到state里的数据 一、 为啥会出…

vuex的原理

1.vuex的作用 vuex是专门为Vuejs应用程序设计的状态管理工具。其实是集中的数据管理仓库。相当于数据库mongoDB等,任何组件都可以存取仓库中的数据。 vuex的组成部分: state:是存储的基本数据。mutations:提交更改数据。getter:对state加工&#xff0c…

vuex 的基本用法

一、vuex是什么? Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态, 这个状态管理应用包含以下几个部分: state,驱动应用的数据源;view,以声明方式将 stat…

DNS风险分析及安全防护研究(三):DNS缓存投毒及防御策略

在前面章节中,我们简单介绍了DNS系统在协议、软件以及结构中脆弱性,并对DNSSEC协议、去中心化结构等安全增强进行了讨论,接下来针对DNS安全所面临的外部攻击威胁和相应的防御策略做下讨论。 1.DNS缓存投毒攻击 在目前各种DNS攻击手段中&…

细说SQL注入:攻击手法与防御策略

一、 SQL注入的基本概念 (一)什么是SQL注入 SQL注入是一种常见的网络攻击技术,它允许攻击者在Web应用程序中插入并执行恶意的SQL代码。这种攻击通常针对的是数据驱动的应用程序,尤其是那些未对用户输入进行充分过滤和处理的应用程…

服务器被cc攻击的简单防御策略(附代码)

CC攻击(也称为网络层攻击或流量攻击)是指企图通过向网站或服务器发送大量伪造的请求,以干扰正常的用户访问的攻击。这些请求可能是来自单个设备的,也可能是来自一群被控制的设备的。为了防御CC攻击,你可以考虑使用以下…

DOS防御策略

该方法能解决一些小型服务的DOS防御问题,成本不高,能在一定程度上起到DOS防御的作用。 原本服务架构 我们的服务器向多个客户机提供服务,这里以腾讯云服务器为例,假设服务商租了一台腾讯云的服务器,一旦服务器收到攻击…

网络安全中的常见攻击类型和防御策略

友情链接:简单实用的IPAD协议框架GeWe框架 网络安全是当前互联网世界中的重要问题。本文将详细介绍常见的网络攻击类型,包括分布式拒绝服务攻击(DDoS)、SQL注入、钓鱼等,并提供相应的防御策略。读者将了解如何识别和应…

会话重放之防御策略、手段

目录 什么是会话重放? 有什么预防手段? 请求添加时间戳或UUID方式实现预防 什么是会话重放? 会话重放是一种攻击方式,攻击者利用先前记录的会话数据来重放或重新发送网络通信流量,以模拟合法用户的身份,…

SQL注入攻击原理及防御策略

一.什么是SQL注入 SQL注入,一般指web应用程序对用户输入数据的合法性没有校验或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执…

安全防御策略trust-untrust-dmz(1)

策略实验 一,规划分析和拓扑图的搭建二,配置思路1,先配置FW000口的IP2,使用IP进入防火墙图形化界面,并且可以创建安全区域3,配置FW100口,其它同理4,配置AR15,配置SERVER2…

浅谈撞库防御策略

2014,12306遭遇撞库攻击,13万数据泄露;2015,乌云网上爆出网易邮箱过亿用户数据由于撞库泄露;数据泄露愈演愈烈,撞库登录成为网站的一大安全威胁,今天小编就和大家探讨一下如何才能够有效的防止撞库攻击。俗语知己知彼,百战不殆,小编在网上找了个撞库教程整理给大家看看…

【UTM使用_入侵防御策略】

UTM使用入侵防御策略 一、网络拓扑图 二、需求描述 外部用户在访问内部的server时启用入侵防御检查;入侵防御策略使用全策略; 三、实验步骤: 配置接口eth1、eth2为路由模式,并设置所需的IP地址 新建IP映射策略,…

网络防御与蓝队实践:探讨网络防御策略、入侵检测系统、安全事件响应等蓝队方面的实际案例和方法

第一章:引言 网络安全一直是当今信息社会中至关重要的话题。随着技术的不断发展,网络威胁也愈发复杂和隐匿。在这样的背景下,网络防御变得尤为重要,蓝队作为网络防御的重要一环,起着至关重要的作用。本文将深入探讨网…

安全世界观 | 常见WEB安全问题及防御策略汇总

1、安全世界观 继上一篇: 我用一个小小的开放设计题,干掉了40%的面试候选人 聊到了Web安全之后,好多朋友也在关注这个话题,今天特意再写一篇。 安全世界观一词是《白帽子讲Web安全》一书的开篇章节,多年后再读经典,仍然…

深度学习的黑魔法防御术:恶意样本(Adversarial Example) 的防御策略综述

随着深度学习(Deep Learning)研究的深入,相关应用已经在许多领域展现出惊人的表现。一方面,深度神经网络(DNN)的强大能力着实吸引着学术界和产业界的眼球。另外一方面,深度学习的安全问题也开始…

CC攻击原理以及如何防御策略

CC攻击原理以及如何防御策略 CC 攻击是一种 DDoS(分布式拒绝服务),它似乎比其他 DDoS 攻击更具技术性。在这种攻击中,看不到假IP,看不到特别大的异常流量,但会导致服务器无法正常连接。 很多创业公司辛辛苦…

服务器安全:浏览器同源策略与跨域请求、XSS攻击原理及防御策略、如何防御CSRF攻击

主要包括 浏览器同源策略与跨域请求XSS攻击原理及防御策略如何使用SpringSecurity防御CSRF攻击CC/DDOS攻击与流量攻击什么是SSL TLS HTTPS? 一、浏览器的同源策略 请求方式:HTTP,HTTPS,Socket等 HTTP请求特点:无状…