当前位置: 首页 > news >正文

vuex原理

浅析vuex的构成

vuex 引入 StateGetter 的概念对状态进行定义;使用 MutationAction对状态进行变更;引入Module对状态进行模块化分割;引入插件对状态进行快照、记录、以及追踪等;提供了mapState、mapGetters、 mapActions、 mapMutations 辅助函数方便开发者在vm中处理store。具体构成关系如下:

vuex部件构成关系图

 

浅析vuex的使用

vuex的使用方式很简单,本文为了剖析源码方便,只进行简单介绍。我们只需要利用vue的use机制将实例化后的store对象注入vue实例即可。如下图:

vuex装载过程图解


Vue.use(Vuex); // 1. vue的插件机制,安装vuex
let store = new Vuex.Store({ // 2.实例化store,调用install方法state,getters,modules,mutations,actions,plugins
});
new Vue({ // 3.注入store, 挂载vue实例store,render: h=>h(app)
}).$mount('#app');

疑问:vuex的store是如何注入到组件中的?

上面的代码得益于vue的插件机制,会在调用vuex的 install方法时,装载vuex。 所以我们直接关注 install方法的实现,其核心代码如下:

Vue.mixin({ beforeCreate: vuexInit });

可见,store注入 vue的实例组件的方式,是通过vue的 mixin机制,借助vue组件的生命周期 钩子 beforeCreate 完成的。即每个vue组件实例化过程中,会在 beforeCreate 钩子前调用 vuexInit 方法。下面,我们将焦点聚焦在 vuexInit 函数。 下面为 vuexInit 的核心代码

this.$store = typeof options.store === 'function'? options.store(): options.store

该代码的核心问题是this的指向,得益于mixin机制,this将指向 vue组件实例。最终,我们可以再 vue组件实例上获得vuex 的store 对象的引用 $store。图示如下:

vuex装载原理图示

结论:vuex利用了vue的mixin机制,混合 beforeCreate 钩子 将store注入至vue组件实例上,并注册了 vuex store的引用属性 $store!

疑问:vuex的state 和 getter 是如何映射到各个组件实例中自动更新的呢?

问题剖析

该问题的核心问题是当store中的 state 和 getter 方式变更时,vuex如何保证各个组件实例中的数据自动更新,并update 组件。简言之,某一组件store更新时,如何通知其他组件进行数据更新,和UI更新。通过简单分析可知,问题的根本就是组件通信的问题

浅谈组件通信

从分析可知,要解答本篇疑问,我们需要从 vue 组件通信谈起。在使用vue的过程中,需要频繁的进行组件间通信。通信的主体之间的关系可以是 父子组件,也可以是 类似兄弟组件或者是无关组件等非父子组件。总的来说有如下几种方式

  1. 通过props向子组件传递数据:父 -> 子
  2. 通过事件向父组件发送消息:子 -> 父,使用$emit发送事件
  3. 父链 和 子索引:this.$parentthis.$children
  4. 依赖注入:provide 和 inject
  5. 子组件引用: ref与$refs
  6. 特性绑定:v-bind="$attrs"v-on="$listeners"
  7. event bus
  8. $dispatch 和 $broadcast : 在vue1中使用
  9. 利用全局变量、storage、cookie、query、hash等传递数据: 非vue特性,不做赘述。
  10. 全局事件广播

我们探讨的是state 和 getter,首先我们先来看一下在vue组件中如何方便的获取 vuex的state和getter

this.$store.state.xxx;
this.$store.state.moduleA.xxx;this.$store.getters.xxx;
this.$store.getters.moduleA.xxx;

正如我们所知的,vuex的Store 会划分出 state 和 getters 两个数据区。getter是从store的state中派生出的状态,代码如下:

// 初始化store时,划分出 state数据区 与 getters数据区
new Vuex.Store({state, getters});

源码分析
首先,我们先来看state。从源码中我们找到了state的get方法

get state () {return this._vm._data.?state}

从源码得知,在vue组件中 使用 this.$store.getters.xxx 获取 xxx 属性时,实际上是获取的store._vm.data.?state 对象上的同名属性。那么我们将关注点放在 _vm上。我们通过Store 的constructor 找到了处理state 和 getter的核心函数resetStoreVM(this, state)。其核心代码如下:


store._vm = new Vue({data: {?state: state}})

上述代码初始化了一个vue实例 _vm,由于vue的data是响应式的,所以,?state也是响应式的,那么当我们 在一个组件实例中 对state.xxx进行 更新时,基于vue的data的响应式机制,所有相关组件的state.xxx的值都会自动更新,UI自然也会自动更新!可见,这和vue的中央事件总线 设计思想如出一辙,同样借助 vue对象特性(响应式的data)作为其他组件的通信桥梁,实现组件间的通信以及数据共享

结论:

  1. vuex的state是借助vue的响应式data实现的。
  2. getter是借助vue的计算属性computed特性实现的。
  3. 其设计思想与vue中央事件总线如出一辙。
http://www.dtcms.com/a/394158.html

相关文章:

  • 内存泄露怎么排查?
  • nginx配置防盗链入门
  • Kafka 多机房、跨集群复制、多租户、硬件与操作系统、全栈监控
  • leetcode136.只出现一次的数字
  • 力扣hot100:环形链表II(哈希算法与快慢指针法思路讲解)
  • 【算法】【Leetcode】【数学】统计1的个数 数位统计法
  • Kafka面试精讲 Day 21:Kafka Connect数据集成
  • MySQL 主从复制完整配置指南
  • 力扣每日一刷Day 23
  • LeetCode 53. 最大子数组和(四种解题思路)包含扩展返回最大和的数组
  • RTX 4090助力深度学习:从PyTorch到生产环境的完整实践指南——高效模型训练与优化策略
  • 23种设计模式之【桥接模式】-核心原理与 Java实践
  • LabVIEW手部运动机能实验
  • 669. 修剪二叉搜索树
  • 大QMT自动可转债申购
  • PolarCTF PWN 网络安全2023秋季个人挑战赛刷题
  • MySQL-day4_02(事务)
  • JUC(8)线程安全集合类
  • springboot中@EnableAsync有什么作用
  • Spark专题-第二部分:Spark SQL 入门(6)-算子介绍-Generate
  • C#练习题——Dictionary
  • Feign
  • SPA小说集之三《森林城市反甩锅战:ERP的权责边界》
  • Qt(模态对话框和非模态对话框)
  • 【无标题】物联网 frid卡控制
  • 【LLM LangChain】 模型绑定工具+调用工具(手动调用/LangGraph/AgentExecutor)+相关注意事项
  • 图神经网络(GNN)入门:用PyG库处理分子结构与社会网络
  • 【C++】编码表 STL简介:STL是什么,版本,六大组件,重要性以及学习方法总结
  • show_interrupts函数的进一步解析及irq_desc结构体
  • Kafka面试精讲 Day 19:JVM调优与内存管理