vuex的深入学习[基于vuex3]----篇(二)

store对象的创建

store的传递图
在这里插入图片描述

在这里插入图片描述

创建语句索引

  1. 创建vuex的语句为new Vuex.Store({…})
  2. Vuex的入口文件是index.js,store是index.js导出的store类
  3. store类是store.js文件中定义的。

Store的构造函数constructor

  1. 判断vuex是否被注入,就是将vue挂载在window对象上,自动检测window.Vue,如果有挂载,而且没有被注册过,则调用注册方法
if (!Vue && typeof window !== 'undefined' && window.Vue) {
      install(window.Vue)
}
  1. 断言
    断言是否被注册,是否支持promise,断言类有没有被正确的实例化,这些断言语句,在vue build出来以后,报错信息会被忽略
if (process.env.NODE_ENV !== 'production') {
      assert(Vue, `must call Vue.use(Vuex) before creating a store instance.`)
      assert(typeof Promise !== 'undefined', `vuex requires a Promise polyfill in this browser.`)
      assert(this instanceof Store, `store must be called with the new operator.`)
}
  • 支持promise语法
  • 已经执行安装函数进行装载
  • 在webpack配置的时候,npm build会将process.env.NODE_ENV 设置为true
function assert(condition, msg) {
    if(!condition) throw new Error(`[vuex] ${msg}`)
}
  1. 部分重要的容器
this._committing = false // 表示状态标识,在严格模式下,防止非commit操作下,state被修改
this._actions = Object.create(null) // action函数的数组的对象,保存所有action回调函数。从null中创建对象,object.create(null)没有继承任何原型方法,也就是说他的原型链没有上一层,从而定义纯粹的对象
this._actionSubscribers = [] // 订阅action操作的函数数组,里面的每个函数,将在action函数被调用之间被调用,该功能类似于插件,和主功能无关。
this._mutations = Object.create(null) // mutation函数的数组的对象,保存所有的mutations回调函数
this._wrappedGetters = Object.create(null) //保存getter函数的函数数组对象容器
this._modules = new ModuleCollection(options) // 解析并生成模块树,通过树结构,保存配置文件内容
this._modulesNamespaceMap = Object.create(null) // 保存命名空间的模块对象,以便在辅助函数createNamespacedHelpers中快速定位到待命名空间的模块。
this._subscribers = []    // 订阅mutation操作的函数数组,里面的每个函数,将在commit执行后被调用,类似于插件,和主功能无关。
this._watcherVM = new Vue() // 定义一个vue对象,vue类将在调用vuex安装函数,install 的时候,被传递进来。

简洁版

this._committing = false // 是否在进行提交状态标识
this._actions = Object.create(null) // acitons操作对象
this._mutations = Object.create(null) // mutations操作对象
this._wrappedGetters = Object.create(null) // 封装后的getters集合对象
this._modules = new ModuleCollection(options) // Vuex支持store分模块传入,存储分析后的modules
this._modulesNamespaceMap = Object.create(null) // 模块命名空间map
this._subscribers = [] // 订阅函数集合,Vuex提供了subscribe功能
this._watcherVM = new Vue() // Vue组件用于watch监视变化

ModuleCollection

this._modules = new ModuleCollection(options)

ModuleCollection函数主要是讲传入的options对象构造为一个module对象,并循环调用(this.register[key], rawModul, false)为其中的modules属性进行模块注册,使得其称为module对象后,最后options对象被构成一个完整的组件树,ModuleCollection类还提供了modules的更替功能。

constructor
export default class ModuleCollection {
    constructor(rawRootModule) {
        this.register([], rawRootModule, false)
    }
}
  • 形参: rawRootModule,在store中new ModuleCollection(options)传入,而options是store的构造函数参数,就是new Vuex.Store({…})传入的参数
{
    state, 
    getters,
    actions,
    mutations  
}
register
register (path, rawModule, runtime = true) {
    if (process.env.NODE_ENV !== 'production') {
        assertRawModule(path, rawModule)
    }
    const newModule = new Module(rawModule, runtime)
    if (path.length === 0) {
        this.root = newModule
    } else {
        const parent = this.get(path.slice(0, -1))
        parent.addChild(path[path.length - 1], newModule)
    }
    if (rawModule.modules) {
        forEachValue(rawModule.modules, (rawChildModule, key) => {
        this.register(path.concat(key), rawChildModule, runtime)
        })
    }
}
参数解析
  • path是注册模块的层级关系数组,保存当前模块及各个祖先模块的名字。[a, b, c, 当前模块] => {modules: {a, modules: {b, module:{当前模块} }}}
  • rawModule是模块的配置参数,在定义模块的时候,开发者定义的模块配置内容,比如state, getter, actions等等
  • runtime标识是否是运行状态,在运行状态下,不能进行某些特定的操作。
assertRawModule
if (process.env.NODE_ENV !== 'production') {
      assertRawModule(path, rawModule)
}
  • 对模块的配置信息进行断言
  • 判断了getters,mtations, actions等配置的数据类型是否正确。
const newModule = new Module(rawModule, runtime),找到module.js文件找到其构造函数
  constructor (rawModule, runtime) {
    this.runtime = runtime
    this._children = Object.create(null) // 定义子模块对象容器
    this._rawModule = rawModule // 保存配置参数本身
    const rawState = rawModule.state // 从配置参数中获得了state这个参数
    this.state = (typeof rawState === 'function' ? rawState() : rawState) || {} // 解析state,如果是函数,则运用工厂模式产生配置对象
  }
根据path模块判断当前是否为根模块
  1. 如果是根模块,则通过this.root进行保存
  2. 如果不是根模块
    • get方法传入的是路径数组,slice(0,-1)是为了去除本模块名,保留所有祖先模块的路径,从而获取夫模块。
    • get函数内部,使用了数组的reduce方法
    get (path) {
        return path.reduce((module, key) => {
          return module.getChild(key)
    }, this.root)
    }
    
      getChild (key) {
        return this._children[key]
      }
      addChild (key, module) {
        this._children[key] = module
      }
    
if(rawModule.modules)判断模块配置信息中,有没有子模块的配置

如果有,则递归调用注册函数register本身,传入的参数加上了子模块名的path模块层级数组,rawchildmodule是子模块配置文件,runtime是继承而来的运行标识符

获取dispatch和commit函数,并复写该函数

const store = this
const { dispatch, commit } = this
this.dispatch = function boundDispatch (type, payload) {
    return dispatch.call(store, type, payload)
}
this.commit = function boundCommit (type, payload, options) {
    return commit.call(store, type, payload, options)
}

复写的作用是将两个函数的this值绑定到vuex实例本身上,防止因为this的指向修改而被修改
这两个函数可以通过mapMutationsmapActions辅助函数转换为Vue中的普通函数,这时this指向Vue组件,而不是Vuex实例

后续代码

this.strict = strict
const state = this._modules.root.state //根据根模块的state变量索引
installModule(this, state, [], this._modules.root)//安装根模块,设置commit,dispatch函数的重载,根据是否设置命名空间,设置参数前缀,将getter,commit,action放到相对应的容器中保存起来。
resetStoreVM(this, state)// 借助vue的watch功能和computed功能,实现数据的响应式
plugins.forEach(plugin => plugin(this)) // 插件的注册,和主功能无关
const useDevtools = options.devtools !== undefined ? options.devtools : Vue.config.devtools
if (useDevtools) { // vue调试工具的处理
    devtoolPlugin(this)
}
installModule(模块安装函数)
参数介绍
  • store: store对象实例,new Vuex.store({…})生成的对象
  • rootState: 根模块的state对象
  • path: 当前模块所处的层级数组
  • module: 模块对象
  • hot
实例代码
  function installModule (store, rootState, path, module, hot) {
  const isRoot = !path.length // 判断当前模块是否为根模块
  const namespace = store._modules.getNamespace(path) //  获取模块的命名空间
  if (module.namespaced) {
    store._modulesNamespaceMap[namespace] = module
  }
  if (!isRoot && !hot) {
    const parentState = getNestedState(rootState, path.slice(0, -1))
    const moduleName = path[path.length - 1]
    store._withCommit(() => {
      Vue.set(parentState, moduleName, module.state)
    })
  }
}

补充
getNamespace

//从跟模块中出发,根据给出的路径数组,递归每一个层级的模块
getNamespace(path) {
    let module = this.root
    return path.reduce((namespace, key) => {
        module = module.getChild(key)
        return namespace + (module.namespaced ? key + "/" : '')
    }, '')
}
{
  moduleA:{
    namespaced:true,
    modules:{
      moduleB:{
          namespaced:false,
          modules:{
            moduleC:{
              namespaced:true,
            }
          }
        }
    }
  }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/736492.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【database2】redis:优化/备份/订阅

文章目录 1.redis安装:加载.conf2.操作:set/get,push/pop,add/rem3.Jedis:java程序连接redis,拿到jedis4.案例_好友列表:json om.4.1 前端:index.html4.2 web:FriendSer…

GIM: Learning Generalizable Image Matcher From Internet Videos

【引用格式】:Shen X, Yin W, Mller M, et al. GIM: Learning Generalizable Image Matcher From Internet Videos[C]//The Twelfth International Conference on Learning Representations. 2023. 【网址】:https://arxiv.org/pdf/2402.11095 【开源代…

使用 axios 进行 HTTP 请求

使用 axios 进行 HTTP 请求 文章目录 使用 axios 进行 HTTP 请求1、介绍2、安装和引入3、axios 基本使用4、axios 发送 GET 请求5、axios 发送 POST 请求6、高级使用7、总结 1、介绍 什么是 axios axios 是一个基于 promise 的 HTTP 库,可以用于浏览器和 Node.js 中…

高职人工智能专业实训课之“图像识别基础”

一、前言 随着人工智能技术的迅猛发展,高职院校对人工智能专业实训课程的需求日益迫切。唯众人工智能教学实训平台作为一所前沿的教育技术平台,致力于为学生提供高效、便捷的人工智能实训环境,特别在“图像识别基础”这一关键课程中&#xf…

JVM 相关知识整理

文章目录 前言JVM 相关知识整理1. 新生代和老年代2. 对象的分配过程3. Full GC /Major GC 触发条件4. 逃逸分析4.1.示例4.2. 使用逃逸分析,编译器可以对代码做如下优化 5. 对象的内存分配6. Minor GC 与 Major GC/Full GC的比较:7. 什么对象进入老年代7.1. 大对象直…

(4) cmake编译静态库和动态库

文章目录 静态库整体代码动态库编译整体代码执行结果(静态) 静态库整体代码 static.h #pragma onecevoid static_demo();static.cpp #include "static.h" #include <iostream>void static_demo(){std::cout<<"static demo"<<std::end…

深度学习增强的非线性光纤单像素成像系统

1、光子器件的逆向设计&#xff1a;通过机器学习&#xff0c;特别是深度学习&#xff0c;可以高效地进行光子器件的逆向设计&#xff0c;这在传统的多参数优化问题中尤为重要。 2、超构表面和超材料设计&#xff1a;机器学习被用于设计具有特定光学特性的超构表面和超材料&…

上位机图像处理和嵌入式模块部署(mcu和swd接口)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 最近学习mcu的时候&#xff0c;接触了不少调试器&#xff0c;这里面有daplink、st-link v2、j-link v9。虽然模块的形状可能不太一样&#xff0c;但…

力扣SQL50 销售分析III having + 条件计数

Problem: 1084. 销售分析III &#x1f468;‍&#x1f3eb; 参考题解 Code select s.product_id,p.product_name from sales s left join product p on s.product_id p.product_id group by product_id having count(if(sale_date between 2019-01-01 and 2019-03-31,1,nu…

OpenAPI

大家好我是苏麟 , 今天带来一个前端生成接口的工具 . 官网 : GitHub - ferdikoomen/openapi-typescript-codegen: NodeJS library that generates Typescript or Javascript clients based on the OpenAPI specification 安装命令 npm install openapi-typescript-codegen --sa…

对接Shopify电商平台的流程

对接Shopify平台的流程通常包括以下关键步骤&#xff0c;在整个对接过程中&#xff0c;需要密切关注Shopify的API使用限制、认证机制、数据隐私政策等&#xff0c;确保应用的安全性和合规性。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合…

43 mysql insert select 的实现

前言 我们这里 来探讨一下 insert into $fields select $fields from $table; 的相关实现, 然后 大致来看一下 为什么 他能这么快 按照 我的思考, 应该里里面有 批量插入才对, 但是 调试结果 发现令我有一些意外 呵呵 果然 只有调试才是唯一的真理 测试数据表如下 CREATE…

企业中订单超时关闭是怎么做的?我说用延迟消息,面试官让我回去等消息?

文章目录 背景时序图方案对比方案一 被动关闭方案二 定时关闭方案三 Rocket MQ延迟消息 总结 背景 订单超时未支付是电商中的一个核心场景&#xff0c;当用户创建订单后&#xff0c;超过一定时间没有支付&#xff0c;平台需要及时将该订单关闭。需要关闭的主要原因有以下几个&…

基于springboot实现问卷调查系统项目【项目源码+论文说明】

基于springboot实现问卷调查系统演示 摘要 传统信息的管理大部分依赖于管理人员的手工登记与管理&#xff0c;然而&#xff0c;随着近些年信息技术的迅猛发展&#xff0c;让许多比较老套的信息管理模式进行了更新迭代&#xff0c;问卷信息因为其管理内容繁杂&#xff0c;管理数…

【database3】oracle:数据交换/存储/收集

文章目录 1.oracle安装&#xff1a;swap&#xff0c;dd1.1 创建swap交换区&#xff1a;grep MemTotal /proc/meminfo &#xff08;安装Oracle物理内存要求1024MB以上&#xff09;&#xff0c;grep SwapTotal /proc/meminfo1.2 安装依赖包及改系统核心参数&#xff1a;关闭一些系…

Selenium进行Web自动化测试

Selenium进行Web自动化测试 SeleniumPython实现Web自动化测试一、环境配置 SeleniumPython实现Web自动化测试 一、环境配置 环境基于win10&#xff08;X64&#xff09; 安装Python&#xff1b;安装PyCham安装chomedriver chomedriver下载地址 可以查看本地chrome软件版本下载…

【雷丰阳-谷粒商城 】【分布式高级篇-微服务架构篇】【13】压力压测JMeter-性能监控jvisualvm

持续学习&持续更新中… 守破离 【雷丰阳-谷粒商城 】【分布式高级篇-微服务架构篇】【13】压力压测JMeter-性能监控jvisualvm 压力测试概述性能指标 JMeter基本使用添加线程组添加 HTTP 请求添加监听器启动压测&查看分析结果JMeter Address Already in use 错误解决 性…

电子电气架构——由NRC优先级引起的反思

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都是你的不对。非必要不费力证明自己,无利益不试图说服别人,是精神上的节…

matplotlib之savefig函数

savefig函数 Matplotlib中&#xff0c;savefig函数用于保存图形为文件。通过该函数&#xff0c;你可以将绘制的图形保存为常见的图像文件格式&#xff0c;如PNG、JPEG、SVG等。 matplotlib.pyplot.savefig(fname, dpiNone, bbox_inchestight, pad_inches0.1, formatNone, tra…

C++封装、继承、多态的应用---职工管理系统

C封装、继承、多态的应用—职工管理系统 文章目录 C封装、继承、多态的应用---职工管理系统1.需求分析2.抽象类的建立2.1抽象基类2.2员工类2.3经理类2.4老板类2.5存储类 3.抽象类的实现4.功能函数的实现4.1菜单功能的实现4.2增加职工功能函数实现4.2显示职工功能函数实现4.3删除…