时隔多年再学习Vuex,什么?原来如此简单!
时隔多年再学习Vuex,什么?原来如此简单!
start
- 写
Vue
写了好多年了,少不了和Vuex
打交道。虽然使用它的次数非常频繁,但是潜意识里总觉得这东西很难,导致遇到与之相关的问题就容易慌张。 - 时至今日,升级版新款 “大菠萝”
pinia
都已经推出了,我居然还是对Vuex
掌握不透彻。这不太好吧? - 那么今天就让这个问题,消失在这篇博客吧!
- 作者:lazy_tomato
- 编写时间:2023/02/16-11/16
官网
Vuex
官方文档
上述链接中
Vuex
版本为3.x
,后续讲解的内容均为此版本。
我后续会依托官方文档,讲讲我对 Vuex
的理解。
本文大部分内容均为我个人的理解,难免有些表述不当之处,参考即可。
一. Vuex
是什么?
1.Vuex是什么?
学习一个东西,首先我们要知道这东西是什么,先来看看官方文档对它的说明:
Vuex
是一个专为 Vue.js
应用程序开发的状态管理模式。
-
状态:状态可以理解为data中的数据;
-
管理:对数据进行管理;
-
模式:可以理解为是一种解决方案;
所以官方文档的话,可以理解为:
Vuex
是一个专为 Vue.js
应用程序开发管理 data
中数据的一个解决方案?
2.为什么要使用 Vuex
?
官方文档已经给了我们答案:
- 多个视图依赖于同一状态。传参的方法对于多层嵌套的组件将会非常繁琐,并且对于兄弟组件间的状态传递无能为力。
- 来自不同视图的行为需要变更同一状态。我们经常会采用父子组件直接引用或者通过事件来变更和同步状态的多份拷贝。
用我自己的理解来表达:
- 多个组件依赖同一个数据,这就涉及到组件之间的数据传参了,如果组件的层级略微复杂,数据的传递会很痛苦。
- 多个组件同时变更一个数据,虽然数据是同一个,但是会有很多无用的拷贝。
3. 问题2
中的哪些痛点的数据有哪些呢,能列举一下吗?
例如:
-
一个网页版的后台管理系统,用户的信息,肯定是很多地方都会使用到的,往往,多个组件都会需要读取这个数据。
-
一个电商的网站,有一个购物车的功能,购物车存储的信息,可能很多组件都会去变更,
4. Vuex
中设计的思想?
Vuex
背后的基本思想,借鉴了 Flux 、Redux和 The Elm Architecture。
这句话介绍了
Vuex
借鉴的思想来源于哪里
Vuex
是专门为 Vue.js
设计的状态管理库,以利用 Vue.js
的细粒度数据响应机制来进行高效的状态更新。
这里介绍了
Vuex
区别于其他库,有哪些特点:更贴合Vue.js
的细粒度数据响应机制。(Vue
响应式的颗粒度精确到对象上每一个属性的变化)
把组件的共享状态抽取出来,以一个全局单例模式管理。在这种模式下,我们的组件树构成了一个巨大的“视图”,不管在树的哪个位置,任何组件都能获取状态或者触发行为!
原话是一个反问句,我适当调整了一下,调整成了陈述句。陈述句阅读起来,给人很直爽的感觉。
核心思想:把共享的数据抽离出来,以全局单例模式管理。
5.什么是单例模式?
要是换做以前,可能这段内容我就跳过了。但是最近刚好学习了设计模式,又刚好学习了单例模式,这里我就讲讲我的理解。
5.1 一般的情况下,我们有一个类,我们可以通过 new 关键词,基于这个类创建多个实例。
例如:
class Tomato {constructor(name) {this.name = name}
}var t1 = new Tomato('红色的番茄')
var t2 = new Tomato('橙色的番茄')console.log(t1)
// { name: '红色的番茄' }console.log(t2)
// { name: '橙色的番茄' }
5.2 单例模式的概念
保证一个类仅有一个实例,并提供一个访问它的全局访问点,这样的模式就叫做单例模式。
我的理解:一个类只能有一个实例
5.3 为什么要用单例模式?
举个例子:
假如,我一个项目组有好几个人。
我在项目搭建的时候,我引入了 Vuex
,做状态管理。
然后我通过 const A = new Vuex()
,创建了一个对象A。我所有的共享数据,都存储在这个对象A中。
当然
new Vuex
只是举例,后续会讲到它的真实用法。
如果其他的小伙伴不知情,也通过 ``const B = new Vuex()` 创建了实例B 。那我想读取和存储共享的数据,到底存储在A还是B呢?
所以这就必须要引入一个 单例模式 的概念。
5.4 如何实现单例模式?
我在编写这篇文章的时候,下载的 Vuex
版本是 4.0,找了很久找不到对应代码了。
**请注意,本文讲解的逻辑主要针对 3.x ** 下方源码对应 Github 地址 ,点击这里
// vuex/src/store.js
function install (_Vue) {// 判断传入的Vue实例对象是否已经被install过Vuex插件(是否有了唯一的state)if (Vue && _Vue === Vue) {if ((process.env.NODE_ENV !== 'production')) {console.error('[vuex] already installed. Vue.use(Vuex) should be called only once.');}return}Vue = _Vue;applyMixin(Vue);
}
自己实现一个 单例模式:
class SingleDog {show() {console.log('我是一个单例对象')}static getInstance() {// 判断是否已经new过1个实例if (!SingleDog.instance) {// 若这个唯一的实例不存在,那么先创建它SingleDog.instance = new SingleDog()}// 如果这个唯一的实例已经存在,则直接返回return SingleDog.instance}
}const s1 = SingleDog.getInstance()
const s2 = SingleDog.getInstance()// true
s1 === s2
好了,说远了,回归到正题。
二. Vuex
如何使用?
1. 安装
npm install vuex --save
2. 引入
import Vue from 'vue'
import Vuex from 'vuex'Vue.use(Vuex)const store = new Vuex.Store({state: {count: 0},mutations: {increment (state) {state.count++}}
})new Vue({el: '#app',store: store, // 这样我们可以
})
Store
英文释义: 仓库
。
主要的用法:
Vue.use(Vuex)
在Vuex
中绑定vue
实例。- 基于
Vuex.Store
,new
出一个实例store
。 - 在
new Vue
的配置对象中,传入store
。方便全局直接this.$store
使用。
3. state
在 new Vuex.Store()
中传入的配置项,主要有五个属性。
- state
状态
- mutations
改变
- actions
行动
- getters
获得
- modules
模块
首先,Vuex
主要是用来管理数据,所以必须要有一个位置可以存储数据。这个位置就是 state。使用时结合计算属性 computed
选项使用。
// 注册:
const store = new Vuex.Store({state: {count: 0},
})// 在组件中使用
const Counter = {template: `<div>{{ count }}</div>`,computed: {count () {return store.state.count}}
}
当一个组件需要获取多个状态的时候,将这些状态都声明为计算属性会有些重复和冗余。为了解决这个问题,我们可以使用 mapState
辅助函数帮助我们生成计算属性,让你少按几次键:
// 在单独构建的版本中辅助函数为 Vuex.mapState
import { mapState } from 'vuex'export default {// ...computed: mapState({// 箭头函数可使代码更简练count: state => state.count,// 传字符串参数 'count' 等同于 `state => state.count`countAlias: 'count',// 为了能够使用 `this` 获取局部状态,必须使用常规函数countPlusLocalState (state) {return state.count + this.localCount}})
}
4. mutations
更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。
同步修改 state 的数据,在 mutations
中定义方法,外部调用这个方法,触发修改。
const store = new Vuex.Store({state: {count: 1},mutations: {increment (state) {// 变更状态state.count++}}
})// 触发更改
store.commit('increment')
5. action
Action 类似于 mutation,不同在于:
- Action 提交的是 mutation,而不是直接变更状态。
- Action 可以包含任意异步操作。
const store = new Vuex.Store({state: {count: 0},mutations: {increment (state) {state.count++}},actions: {increment (context) {context.commit('increment')}}
})
6. getters
Vuex 允许我们在 store 中定义“getter”(可以认为是 store 的计算属性)。就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
const store = new Vuex.Store({state: {todos: [{ id: 1, text: '...', done: true },{ id: 2, text: '...', done: false }]},getters: {doneTodos: state => {return state.todos.filter(todo => todo.done)}}
})store.getters.doneTodos // -> [{ id: 1, text: '...', done: true }]
7. modules
由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。
为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:
const moduleA = {state: () => ({ ... }),mutations: { ... },actions: { ... },getters: { ... }
}const moduleB = {state: () => ({ ... }),mutations: { ... },actions: { ... }
}const store = new Vuex.Store({modules: {a: moduleA,b: moduleB}
})store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态// 使用:
store.state.a.xxx
三.思考
截止到这里,对Vuex的基础使用,算是基本掌握了。
记录一下我自己的思考。
- 使用Vuex的目的:解决多个组件依赖,多个组件需要修改的数据,共享的问题。
- 同步修改,使用 commit的方式,触发 mutation;
- 异步修改,使用 dispatch的方式,触发 action;
- getters 相当于过滤器,用于处理数据格式。
- modules 用于将一个大的 state,拆分多个模块。访问的时候,中间穿插模块名。
也没什么好恐怖的,其实很简单,简单来说,就是一个全局单例的一个对象,存储我们频繁使用的需要共享的数据。
相关文章:
时隔多年再学习Vuex,什么?原来如此简单!
时隔多年再学习Vuex,什么?原来如此简单! start 写 Vue 写了好多年了,少不了和 Vuex 打交道。虽然使用它的次数非常频繁,但是潜意识里总觉得这东西很难,导致遇到与之相关的问题就容易慌张。时至今日,升级版…...
Linux笔记_gcc
Linux_gcc程序的翻译链接库make与makefile关于gcc的一些笔记。 程序的翻译 gcc/g是一个编译器。 预处理:头文件展开、条件编译、宏替换、去注释 编译:C语言汇编语言 汇编:汇编->可重定位目标二进制文件,不可以被执行࿰…...
2023美赛MCM A题 详细思路
2023美赛(MCM/ICM)如期开赛,为了尽早的帮大家确定选题。这里我们加急为大家编辑出A赛题详细思路,方便大家快速对A题目的难度有个大致的了解。同时,我们也给出了A题目简要的解题思路,以及该问题在实际解决中可能会遇到的难点。A题的…...
c#: NetTopologySuite凹凸多边形计算
环境: .net 6.0NetTopologySuite 2.5.0vs2022平面二维 一、夹角计算 1.1 计算向量与x轴正方向的夹角 方法: AngleUtility.Angle(Coordinate p) 下图上的t2即为p,之所以这么写是为了和AngleUtility.AngleBetweenOriented做比较 注意: 结果…...
NFT Insider #86:A16z 领投,YGG 获得 1380 万美元融资,The Sandbox与《北斗神拳》合作
引言:NFT Insider由NFT收藏组织WHALE Members、BeepCrypto联合出品,浓缩每周NFT新闻,为大家带来关于NFT最全面、最新鲜、最有价值的讯息。每期周报将从NFT市场数据,艺术新闻类,游戏新闻类,虚拟世界类&#…...
Sort_Algorithm
排序算法前言插入排序折半插入排序希尔排序冒泡排序快速排序选择排序堆排序归并排序前言 排序算法:将一堆数据元素按关键字递增或者递减的顺序,进行排序。 排序算法的评价指标:时间复杂度,空间复杂度,算法稳定性。 算…...
【初探人工智能】2、雏形开始长成
【初探人工智能】2、雏形开始长成【初探人工智能】2、雏形开始长成安装Flask封装Web接口雏形设置接收参数功能验证聊天写代码代码补全生成图片写在后面笔者初次接触人工智能领域,文章中错误的地方还望各位大佬指正! 【初探人工智能】2、雏形开始长成 在…...
【LeetCode】剑指 Offer(2)
目录 写在前面: 题目: 题目的接口: 解题思路: 代码: 过啦!!! 写在最后: 写在前面: 今天的每日一题好难,我不会dp啊啊啊啊啊啊。 所以&am…...
【JavaSE】Lambda、Stream(659~686)
659.每天一考 1.写出获取Class实例的三种常见方式 Class clazz1 String.class; Class clazz2 person.getClass(); //sout(person); //xxx.yyy.zzz.Person... Class clazz3 Class.forName(String classPath);//体现反射的动态性2.谈谈你对Class类的理解 Class实例对应着加载…...
有限差法(Finite Difference)求梯度和Hessian Matrix(海森矩阵)的python实现
数学参考 有限差方法求导,Finite Difference Approximations of Derivatives,是数值计算中常用的求导方法。数学上也比较简单易用。本文主要针对的是向量值函数,也就是f(x):Rn→Rf(x):\mathbb{R^n}\rightarrow \mathbb{R}f(x):Rn→R当然&…...
day33 贪心算法 | 1005、K次取反后最大化的数组和 134、加油站 135、分发糖果
题目 1005、K次取反后最大化的数组和 给定一个整数数组 A,我们只能用以下方法修改该数组:我们选择某个索引 i 并将 A[i] 替换为 -A[i],然后总共重复这个过程 K 次。(我们可以多次选择同一个索引 i。) 以这种方式修改…...
《蓝桥杯每日一题》递推·AcWing 3777. 砖块
1.题目描述n 个砖块排成一排,从左到右编号依次为 1∼n。每个砖块要么是黑色的,要么是白色的。现在你可以进行以下操作若干次(可以是 0 次):选择两个相邻的砖块,反转它们的颜色。(黑变白…...
mysql读写分离(maxscale)
1. 环境架构 需要三台服务器。192.168.2.10(master)192.168.2.20(slave)192.168.2.30(maxscale) 2. 部署mysql主从同步 mysql主从同步可以参考mysql主从同步 3. 部署maxscale服务 MaxScale中间件软件 …...
第八章 - 数据分组( group by , having , select语句顺序)
第八章 - 数据分组 group by数据分组过滤分组 having分组排序groub by语句的一些规定select语句顺序数据分组 在使用group by进行分组时,一般都会配合聚合函数一起使用,实现统计数据的功能。比如下面例子,需要按性别计算人数。按性别进行分组…...
Git(GitHub,Gitee 码云,GitLab)详细讲解
目录第一章 Git 概述1.1 何为版本控制1.2 为什么需要版本控制1.3 版本控制工具1.4 Git 简史1.5 Git 工作机制1.6 Git 和代码托管中心第二章 Git 安装第三章 Git 常用命令3.1 设置用户签名3.2 初始化本地库3.3 查看本地库状态3.3.1 首次查看(工作区没有任何文件&…...
策略模式(Strategy Pattern)
编写鸭子项目,具体要求如下: 1) 有各种鸭子(比如 野鸭、北京鸭,水鸭等,鸭子有各种行为,比如 叫,飞行等) 2)显示鸭子的信息 传统方案解决鸭子问题 1࿰…...
《Qt6开发及实例》6-2 Qt6基础图形的绘制
目录 一、绘图框架设计 二、绘图区的实现 2.1 PaintArea类 2.2 PaintArea类讲解 三、主窗口的实现 3.1 MainWidget类 3.2 MainWidget类讲解 3.3 槽函数编写 3.5 其他内容 一、绘图框架设计 界面 两个类 二、绘图区的实现 2.1 PaintArea类 paintarea.h #ifndef…...
LeetCode 382. 链表随机节点
原题链接 难度:middle\color{orange}{middle}middle 题目描述 给你一个单链表,随机选择链表的一个节点,并返回相应的节点值。每个节点 被选中的概率一样 。 实现 SolutionSolutionSolution 类: Solution(ListNodehead)Solution…...
iOS开发AppleDeveloper中给别人授权开发者权限后,对方一直显示不了我的开发账号team
在iOS开发经常出现多人协作开发的情况。这时我们通常要发邮件邀请别的用户为开发者或者app管理就可以开发我们自己的项目了。但是这次我给别人授权开发者权限后,发现别人权限中没有证书相关权限如图:并且别人登录该账号后,在xcode中只有一个看…...
FreeRTOS数据类型和编程规范
目录 数据类型 变量名 函数名 宏的名 数据类型 每个移植的版本都含有自己的portmacro.h头文件,里面定义了2个数据类型 TickType_t FreeRTOS配置了一个周期性的时钟中断:Tick Interrupt每发生一次中断,中断次数累加,这被称为t…...
【python知识】win10下如何用python将网页转成pdf文件
一、说明 本篇记录一个自己享用的简单工具。在大量阅读网上文章中,常常遇到一个专题对应多篇文章,用浏览器的收藏根本不够。能否见到一篇文章具有搜藏价值,就转到线下,以备日后慢慢消化吸收。这里终于找到一个办法,将在…...
C语言常见关键字
写在前面 这个博客是结合C语言深度解剖这本书和我以前学的知识综合而成的,我希望可以更见详细的谈一下C语言的关键字,内容有点多,有错误还请斧正. 常见关键字 下面我们说下C语言的关键字,所谓的关键字是指具有特定功能的单词,我们可以使用关键字来帮助我们完成不同的事物.C语…...
【MT7628】固件开发-SDK4320添加MT7612E WiFi驱动操作说明
解压5G WiFi MT7612E驱动1.1解压指令 tar -xvf MT76x2E_MT7620_LinuxAP_V3.0.4.0_P2_DPA_20160308.tar.bz2 1.2解压之后会出现以下两个目录 rlt_wifi rlt_wifi_ap 1.3将解压后的文件拷贝到系统下 拷贝路径 RT288x_SDK/source/linux-2.6.36.x/drivers/net/wireless 内核中打开驱…...
如何从手工测试进阶自动化测试?阿里10年测开经验分享...
随着行业的竞争加剧,互联网产品迭代速度越来越快,QA 与测试工程师都需要在越来越短的测试周期内充分保证质量。可是,App 测试面临着很多挑战,比如多端发布、多版本发布、多机型发布等等,导致了手工测试很难完全胜任。因…...
C++复习笔记11
1. vector是表示可变大小数组的序列容器。 2. 就像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素进行访问,和数组一样高效。但是又不像数组,它的大小是可以动态改变的,而且它的大小会被…...
【MT7628】固件开发-SDK4320添加MT7628 WiFi驱动操作说明
解压2.4G WiFi MT7628驱动1.1解压指令 tar -xvf MT7628_LinuxAP_V4.1.0.0_DPA_20160310.tar.bz2 1.2解压之后会出现以下两个目录 mt_wifi mt_wifi_ap 1.3将解压后的文件拷贝到系统下 拷贝路径 RT288x_SDK/source/linux-2.6.36.x/drivers/net/wireless 内核中打开驱动编译修改R…...
C#开发的OpenRA游戏加载界面的实现
C#开发的OpenRA游戏加载界面的实现 游戏的UI是一个游戏必备, 但是游戏的UI都是自己处理的,不能使用像Windows自带的UI。 这样游戏的UI,其实也是使用游戏的方式来显示的, 只不过使用了低帧率的方式来显示。 比如OpenRA游戏界面,就会显示如下: 游戏的界面有很多,先从一个简…...
渲染农场优势是什么_云渲染农场怎么用?
在回答渲染农场的优势这个问题之前,我先申明一下本文中提到的渲染农场/云渲染平台/云渲染农场,都特指CG领域内的专业3D渲染平台,有一些文章会强调这个叫法的区别,但是业内一般都不会分这么细,所以也就不赘述了。渲染农…...
SoapUI、Jmeter、Postman三种接口测试工具的比较分析
目录 前言 1. 用例组织方式 2. 支持的接口类型与测试类型 3. 配置不同接口类型 4. 自定义变量以及变量的作用域 5. 数据源、生成器,进行参数化 6. 流程控制 7. 结果解析、展示 8. 断言 9. 脚本扩展能力 10. 团队协作 总结 重点:配…...
Python内置函数 — sort,sorted
1、sort 列表的属性方法,对列表进行排序,默认升序,返回None值。 源码注释: """ Sort the list in ascending order and return None.The sort is in-place (i.e. the list itself is modified) and stable (i.e.…...
为什么要找对做网站的公司/百度图片查找
1. 进程数设置 processes 4 2. 线程数设置 threads 40 3. 超时设置 harakiri-verbose true harakiri 300 4. 缓冲区设置 post-buffering 65536 # 不设置会导致上传大文件失败 buffer-size 65536 5. pythonpath设置,可以有多个 pythonpath /path1 p…...
官方网站链接如何做/磁力宅
1.汇编中的移位指令 算数移位指令 指令格式:SAL/SAR Reg/Mem, CL/ImmSAL(Shift Arithmetic Left):算数左移 SAR(Shift Arithmetic Right):算数右移 逻辑移位指令 指令格式:SHL/SHR Reg/Mem, CL/ImmSHL(Shift Left):逻辑左移 SHR(Shift Right):逻辑右移 循…...
靠谱的代运营公司有哪些/seo广告优化
原标题:【表扬信】一封来自福州大学至诚学院的表扬信自2020年初国科科技与福州大学至诚学院计算机工程系开展产学研合作以来,国科科技为该系2020年的教学工作提供了专业的教学服务,主要承担了入侵检测与安全扫描技术、网络安全架构、网络空间…...
艾奇视觉网站建设/app软件开发
线程发生死锁可能性很小,即使看似可能发生死锁的代码,在运行时发生死锁的可能性也是小之又小。发生死锁的原因一般是两个对象的锁相互等待造成的。在《Java线程:线程的同步与锁》一文中,简述死锁的概念与简单例子,但是…...
台州做鞋子网站/合肥网站维护公司
#/usr/bin/env python name input("please input your name:") print(name)运行时出现下面的情况:please input your name:彭春彭春转载于:https://blog.51cto.com/11273036/1867049...
网站建设目标论文/电脑培训学校在哪里
刚开始接触网络的时候,都必须得学习 OSI 模型,很多人不以为然! 但是该模型,对于项目中的技术实施与故障定位与排查,具有极其重要的意义! 少年,慢慢体会~~ 附件:http://down.51cto.co…...