Vuex从入门到精通
1|0一、vuex介绍
1|1目标
- 什么是Vuex
- 为什么学习Vuex
1|2通信方案
组件关系 | 数据通信 |
---|---|
父子关系 | 父传子:props ; 子传父:$emit |
非父子关系 | vuex (一种组件通信方案) |
1|3Vuex是什么
-
概念:专门在 Vue 中实现集中式状态(数据)管理的一个 Vue 插件,对 vue 应 用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方 式,且适用于任意组件间通信。
-
Vuex 实现了一个单向数据流,在全局拥有一个 State 存放数据,当组件要更改 State 中的数据时,必须通过 Mutation 提交修改信息, Mutation 同时提供了订阅者模式供外部插件调用获取 State 数据的更新。而当所有异步操作(常见于调用后端接口异步获取更新数据)或批量的同步操作需要走 Action ,但 Action 也是无法直接修改 State 的,还是需要通过Mutation 来修改State的数据。最后,根据 State 的变化,渲染到视图上。
- Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
- 改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样可以方便地跟踪每一个状态的变化。
-
原理如图所示:
1|4vuex为何学
程序页面多, 数据变量多
- 不同组件数据保持同步
- 数据的修改都是可追踪
一个户外商店有两名员工,张三和李四
一天的早上,他们分别对帐篷的数量做了一次盘点,发现一共有三个帐篷
张三卖出去俩个,他以为库存里还有一个
李四卖出去一个,他以为库存里还有两个
而事实上是,库存现在已经为零
如果他们再接受客户的预订,就会出现库存不足的情况
张三和李四因为没有保持库存的数量的同步导致了尴尬,这个就是所谓的
数据保持同步
店长需要知道, 谁卖出了多少个帐篷,这个行为我们称之为
数据修改是可追踪的
图示:
1|5Vuex中存什么
多个组件共享状态,才存储在Vuex中
某个组件中的私有数据,依旧存储在data中
例如:
-
登陆的用户名需要在首页, 个人中心, 结算页面使用, 用户名存在Vuex中
-
文章详情数据, 只有在文章详情页查看, 在自身data中声明
1|6小结
- 什么是Vuex
- Vuex是Vue官方推荐的集中式状态管理机制
- 为何学Vuex
- 数据同步, 集中管理
- Vuex中存什么
- 多个组件共享的值
2|0二、Vuex学习内容
2|1目标
- 知道Vuex要学习什么
2|2核心概念
-
安装(固定)
-
配置项(固定)
配置项 含义 注意 state 单一状态树 类似data mutations 数据管家(同步) 唯一修改state地方 actions 异步请求 要改state需要提交给mutations getters vuex计算属性 类似computed modules 模块拆分
2|3图示关系
单一定义store对象, 里面5个配置项, 在任意组件可以使用
2|4小结
- Vuex五个核心概念是?
- state / mutations / actions / getters / modules
3|0三、Vuex例子准备
3|1目标
3|2工程准备
-
初始化新的工程 vuex-demo
-
清空欢迎界面
-
并设置如下三个组件, 目录如下:
3|3App.vue
复制标签和样式, 引入AddItem和SubItem2个子组件显示
3|4AddItem.vue
3|5SubItem.vue
3|6小结
- App下套用了AddItem和SubItem, 要在3个组件共享一个数据
4|0四、vuex-store准备
4|1目标
- 创建store仓库
- 注入到Vue项目中
4|2store概念
每个 Vuex 应用的核心 store(仓库), 包含5个核心概念
4|3Vuex目录
和路由模块router/index.js - 类似, 维护项目目录的整洁,新建src/store/index.js文件
当然, 这个步骤并不是必需的
4|4使用步骤
-
工程中 - 下载vuex
-
store/index.js - 创建定义导出store对象
-
main.js - 导入注入到Vue中
请再次回忆一下vue-router的用法,是不是很像?
4|5小结
-
vuex的核心是什么?
- store对象(包含5个核心属性)
-
如何创建store对象?
- 工程下载vuex模块
- store/index.js
- 引入注册
- 生成store对象导出
- main.js - 导入注入
5|0五、vuex-state数据源
5|1目标
- 定义state
- 直接使用state
- 辅助函数mapState
state是唯一的公共数据源,统一存储
5|2定义state
在store/index.js定义state
语法:
具体代码:
5|3使用state2种方式
-
方式1: 组件内 - 直接使用
语法:
-
方式2: 组件内 - 映射使用 (推荐)
语法:
5|4AddItem直接用
5|5App.vue直接用
计算属性count, 和输入框的v-model双向绑定
5|6SubItem映射用
整个过程的示意图如下
5|7注意
state是响应式的, 只要state值变化, 页面上使用的地方会自动更新同步
5|8小结
-
state作用?
定义全局状态数据源
-
state如何定义?
在store内, state:
-
state的值如何用到具体vue组件内?
- 直接使用 this.$store.state.变量名
- 映射使用 ...mapState(['state的变量名'])
6|0六、vuex-mutations定义-同步修改
6|1目标
- 定义mutations
6|2定义mutations
mutations类似数据管家, 操作state里的数据
在store/index.js定义mutations
语法:
具体代码
6|3注意
- mutations是唯一能修改state的地方, 确保调试工具可以追踪变化
- mutations函数内, 只能写同步代码, 调试工具可追踪变化过程
- 因为调试工具要立刻产生一次记录, 所以必须是同步的
6|4小结
-
mutations里函数作用?
- 负责修改state里的数据
-
mutations只能写什么样的代码?
- 同步流程的代码
7|0七、vuex-mutations使用
7|1目标
- 使用mutations2种方式
- mutations注意事项
7|2使用mutations的2种方式
-
方式1: 组件内 - 直接使用
语法:
-
方式2: 组件内 - 映射使用
语法:
7|3AddItem直接用
- 点击事件绑定
- 提交mutations传入值
7|4App.vue直接用
- 触发计算属性的set方法
- 提交mutations传入值
7|5SubItem映射用
- 点击事件
- 映射mutations的方法
- 调用mutations方法传值
7|6注意
mutations函数上, 只能接收一个参数值, 如果传对个, 请传一个对象
7|7小结
-
mutations有哪2种使用方式?
直接使用 this.$store.commit()
映射使用 mapMutations把方法映射到组件内直接调用
-
state, mutations, 视图组件, 3个关系是什么?
8|0八、vuex-actions定义-异步修改
8|1目标
- 定义actions
8|2定义actions
在store/index.js定义actions
语法:
具体代码:
8|3小结
-
actions和mutations区别?
mutations里同步修改state
actions里放入异步操作
-
actions是否能操作state?
不建议, 要commit给mutations(为调试工具可追踪)
-
actions和mutations里函数, 第一个形参分别是什么?
mutations的是state
actions的是store
9|0九、vuex-actions使用
9|1目标
- 使用actions
9|2使用actions的2种方式
-
方式1: 组件内 - 直接使用
语法:
-
方式2: 组件内 - 映射使用
语法:
9|3AddItem直接用
- 点击事件
- dispatch触发action
9|4SubItem映射用
- 点击事件
- 映射actions的方法
- 调用actions的方法传值
9|5小结
-
actions使用方式?
方式1: this.$store.dispatch('actions方法名字', 值)
方式2: ...mapActions(['actions里的方法名']) 映射到原地使用
-
视图组件, state, mutations, actions的关系是?
10|0十、vuex-重构购物车-准备Store
10|1目标
- 在现有项目如何集成vuex
10|2store准备
- 复制预习资料<shopcar-模板>到自己今天文件夹下
- 下载vuex
- store/index.js创建导出store对象
- main.js把store引入, 然后注入到Vue实例
10|3小结
-
现有项目如何集成vuex
下载vuex
创建store对象并注入到Vue实例中
11|0十一、vuex-重构购物车-配置项(上午结束)
11|1目标
- 准备state和mutations还有actions
11|2配置项准备
- 定义state - 保存商品列表数组
- 定义mutations - 给state里变量赋值
- 定义actions - 异步请求数据提交给mutations
11|3App.vue使用vuex
- 把vuex商品数组映射回来使用
- 网络请求调用actions方法
11|4小结
-
mapState可以改变映射到原地的计算属性名吗?
可以的, 格式...mapState({''计算属性名', 'state里要映射的变量名'})
12|0十二、vuex-getters定义-计算属性
12|1目标
- getters概念
- 定义getters
12|2getters概念
vuex身上的全局状态-计算属性, 类似于computed
getters 依赖于 state中原始数据的变化,并返回计算后的新数据
12|3定义getters
在store/index.js定义getters
语法:
具体代码
12|4小结
-
getters有什么用?
vuex里的计算属性, 属于全局计算属性, 类似computed
13|0十三、vuex-getters使用
13|1目标
- 组件内使用getters
13|2使用getters的2种方式
-
方式1: 组件内 - 直接使用
语法:
-
方式2: 组件内 - 映射使用
语法:
13|3MyFooter.vue里使用
- 使用2种方式给计算属性值
13|4小结
-
getters如何使用?
方式1: this.$store.getters.计算属性名
方式2: ...mapGetters(['getters里计算属性名'])
14|0十四、vuex-modules定义-分模块
14|1目标
- 为何要分模块
- modules定义
14|2为何分模块
14|3代码上的对比
14|4创建modules模块对象
- 新建store/modules/user.js
- 新建store/modules/cart.js
语法: 对象里包含5个核心概念, 只有state变成函数形式
user.js - 用户模块对象
cart.js - 购物车模块对象
14|5定义modules
语法:
- 把2个模块对象, 引回到store里注册
14|6小结
-
为什么分模块?
集中式管理项目过大, 变量过多, 会导致state臃肿, 难以维护
-
如何分模块?
定义模块对象, state变成函数返回对象形式, 每个模块都有state/mutations/actions/getters/modules
-
根store如何注册?
modules里 { 模块名: 模块对象 }
15|0十五、分模块-影响state取值方式
15|1目的
- 只要分模块, state取值方式改变, 其他暂时不变
15|2state使用方式修改
-
方式1: 组件内 - 直接使用
原语法:
分模块后语法:
-
方式2: 组件内 - 映射使用
原语法:
分模块后语法:
15|3App.vue-修改
15|4小结
-
分模块对什么有影响?
对state的取值方式有影响, 对其他暂无影响
-
state如何取值?
在组件使用的时候, 要state.模块名.变量名
16|0十六、分模块-命名空间
16|1目标
- 防止多个模块之间, mutations/actions/getters的名字冲突
16|2开启命名空间
在模块对象内设置namespaced: true
16|3state使用方式修改
-
直接使用无变化: this.$store.state.模块名.变量名
-
辅助函数需要遵守格式
16|4mutations使用方式修改
-
方式1: 组件内 - 直接使用
-
原语法:
-
开命名空间后语法:
-
-
方式2: 组件内 - 映射使用
-
原语法:
-
开命名空间后语法:
-
16|5actions使用方式修改
-
方式1: 组件内 - 直接使用
-
原语法:
-
开命名空间后语法:
-
-
方式2: 组件内 - 映射使用
-
原语法:
-
开命名空间后语法:
-
16|6getters使用方式修改
-
方式1: 组件内 - 直接使用
-
原语法:
-
开命名空间后语法:
-
-
方式2: 组件内 - 映射使用
-
原语法:
-
开命名空间后语法:
-
16|7小结
- state和mutations, 在根store和开启命名空间里的区别?
17|0十七、Vuex的构造
17|11.actions
- 由子组件this.$store.dispatch('actions名',传递的数据)触发
- 传递的数据只能是单个数据,多个数据用对象传递
- actions: { action名({commit},数据){...}}
- store中actions内,commit用于触发mutations,actions只做业务逻辑,不修改state
17|22.mutations
- 由actions中的commit('mutations名',传递的数据)触发
- mutations:{mutations名(state,数据){...}}
- store中的mutations内,mutations可以修改state中的数据
17|33.state
- 存储数据:state:{userInfor:
- 可以通过mutations存储或者修改,也是getters里面计算属性的依据
17|44.getters
- 计算state中的数据:getters:{getters名(state){...}}
- state用于getters计算属性的依据
18|0十八、Vuex中的模块(module)和命名空间(namespaced)
18|11.模块(module)
- 由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。
为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的state、mutations、actions、getters、甚至是嵌套子模块。
18|22.命名空间(namespaced)
-
默认情况下,模块内部的 actions、mutations 和 getters 是注册在全局命名空间的——这样使得多个模块能够对同一 mutations 或 actions 作出响应,如果希望你的模块具有更高的封装度和复用性,你可以通过添加 namespaced: true 的方式使其成为带命名空间的模块。当模块被注册后,它的所有 getters、actions 及 mutations 都会自动根据模块注册的路径调整命名。
-
如果你想模块之间相互独立、互不影响。可以通过添加 namespaced: true 的方式使其成为带命名空间的模块,当模块被注册后,它的所有 getters、actions 和 mutations 都会自动根据模块注册的路径调整命名。所以开启命名空间的模块中的getters、actions 和 mutations的使用方式都会改变;但是开启命名空间和不开启命名空间的模块中的state的使用方式不会改变。格式依然是store.state.模块名.状态名。
19|0扩展: 使用Devtools调试vuex数据
优秀的调试工具可以使我们写程序事半功倍,最后我们再学习一下如果使用dev-tools来调试vuex中的数据,这也是数据可预测特性里不可缺少的一环
19|1目标
- 掌握dev-tools调试vuex
- 理解什么是数据状态是可追踪的
19|2如何进行调试
注意只有vue+vuex的项目才可以用
19|3调试信息说明
__EOF__
本文链接:https://www.cnblogs.com/P1Kaj1uu/p/16997722.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了