时隔多年再学习Vuex,什么?原来如此简单!

news2024/11/18 23:39:06

时隔多年再学习Vuex,什么?原来如此简单!

start

  1. Vue 写了好多年了,少不了和 Vuex 打交道。虽然使用它的次数非常频繁,但是潜意识里总觉得这东西很难,导致遇到与之相关的问题就容易慌张。
  2. 时至今日,升级版新款 “大菠萝” pinia 都已经推出了,我居然还是对 Vuex 掌握不透彻。这不太好吧?
  3. 那么今天就让这个问题,消失在这篇博客吧!
  4. 作者:lazy_tomato
  5. 编写时间: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 英文释义: 仓库

主要的用法:

  1. Vue.use(Vuex)Vuex 中绑定 vue 实例。
  2. 基于 Vuex.Storenew 出一个实例 store
  3. new Vue 的配置对象中,传入 store。方便全局直接 this.$store 使用。

3. state

new Vuex.Store() 中传入的配置项,主要有五个属性。

  1. state 状态
  2. mutations 改变
  3. actions 行动
  4. getters 获得
  5. 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的基础使用,算是基本掌握了。

记录一下我自己的思考。

  1. 使用Vuex的目的:解决多个组件依赖,多个组件需要修改的数据,共享的问题。
  2. 同步修改,使用 commit的方式,触发 mutation;
  3. 异步修改,使用 dispatch的方式,触发 action;
  4. getters 相当于过滤器,用于处理数据格式。
  5. modules 用于将一个大的 state,拆分多个模块。访问的时候,中间穿插模块名。

也没什么好恐怖的,其实很简单,简单来说,就是一个全局单例的一个对象,存储我们频繁使用的需要共享的数据。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CDH 6.3.2 升级Hive 2.3.9

升级背景 DolphinScheduler 3.1.1安装好后&#xff0c;其源码中集成的是Hive 2.1.1&#xff0c;版本太低&#xff0c;当在数据中心连接Hive数据源时报错&#xff0c;所以升级CDH自带的Hive为2.3.9版本。 一、准备工作 1、下载hive2.3.9并解压 下载地址&#xff1a;http://a…

世界前沿3D开发工具HOOPS 2023震撼发布,核心功能再升级

HOOPS SDK简介 HOOPS SDK是全球领先开发商TechSoft 3D旗下的原生产品&#xff0c;专注于Web端、桌面端、移动端3D工程应用程序的开发。长期以来&#xff0c;HOOPS通过卓越的3D技术&#xff0c;帮助全球600多家知名客户推动3D软件创新&#xff0c;这些客户包括SolidWorks、SIEM…

springboot+vue学生考勤请假管理系统

管理员&#xff1a; 系统用户管理&#xff1a;针对系统的管理员用户&#xff0c; 系统用户的基本信息情况&#xff0c;进行管理。 教师管理&#xff1a;可以对教师权限的用户信息进行管理。并且能过实现教师信息的查看&#xff0c;密码修改等。 学生管理&#xff1a;对学生用户…

Unreal Engine06:Actor的实现

写在前面 Actor是可以放进地图的最基本类&#xff0c;这里主要是介绍一下Actor的使用。 一、空间坐标系 1. Actor的变换操作 Actor的变换变换操作主要包括四个部分&#xff1a; 位置&#xff1b;旋转&#xff1b;缩放&#xff1b; 上面三者都是对应三个轴进行变换&#xff1…

IP SAN组网配置

目录一、确认网络连接畅通二、服务器端ISCSI启动器配置1.以root身份登录2.验证是否已安装iSCSI启动器3.安装iSCSI启动器4.启动iSCSI服务5.给iSCSI启动器命名6.扫描目标器7.登录目标器8.将登录目标器行为设置为自启动三、主机多路径配置四、存储配置五、主机挂载背景&#xff1a…

ubuntu20.04配置UR机械臂的仿真环境

ubuntu20.04配置UR机械臂的仿真环境 参考链接 1. 首先安装好ROS ubuntu20.04安装Noetic版本的ros&#xff0c;具体安装可见之前写的博客 2. 配置UR机械臂仿真工具包 找一个你喜欢的地方创建ros工作空间&#xff08;也就是找个文件夹放ros的包&#xff0c;然后编译运行&…

03 路由匹配

封装了框架的 Context&#xff0c; 将请求结构 request 和返回结构 responseWriter 都封装在 Context 中。利用这个 Context&#xff0c; 我们将控制器简化为带有一个参数的函数 FooControllerHandler&#xff0c;这个控制器函数的输入和输出都是固定的。在框架层面&#xff0c…

MySQL(二)表的操作

一、创建表 CREATE TABLE table_name ( field1 datatype, field2 datatype, field3 datatype ) character set 字符集 collate 校验规则 engine 存储引擎; 说明&#xff1a; field 表示列名 datatype 表示列的类型 character set 字符集&#xff0c;如…

如何创建你的公司的FAQ页面?

很多企业考虑为公司搭建一个“常见问题”页面&#xff0c;作为帮助客户回答关于产品和服务的常见问题的一种方式。 FAQ页面和登录/销售页面不同&#xff0c;没有展现出直接的投资回报&#xff0c;但是为团队节省了其他成本&#xff0c;据了解&#xff0c;高达67%的客户相比于跟…

STM32 - 看门狗

独立看门狗 IWDG专业时钟LSI 低功耗仍可以运行对定时的控制比较松喂狗这些时间是按照40kHz时钟给出。实际上&#xff0c;MCU内部的RC频率会在30kHz到60kHz之间变化。此外&#xff0c;即使RC振荡器的频率是精确的&#xff0c;确切的时序仍然依赖于APB接口时钟与RC振荡器时钟之间…

浅谈IDE 和代码编辑器之间有什么区别?

您希望如何完成日常编码&#xff1f;快速地&#xff1f;明显地。以既不重复也不单调的方式&#xff1f;自然。拥有您可能随时需要的所有工具。 是否会得到这一切取决于选择在哪里编写代码。您在这里的两个主要选择是代码编辑器或 IDE。两者都旨在使您的编码更容易 - 但是&…

使用 PyNeuraLogic 超越 Transformers

展示神经符号编程的力量neuro-symbolic1. 简介 在过去的几年里&#xff0c;我们看到了基于 Transformer 的模型的兴起&#xff0c;并在自然语言处理或计算机视觉等许多领域取得了成功的应用。在本文[1]中&#xff0c;我们将探索一种简洁、可解释和可扩展的方式来表达深度学习模…

捕获最小化窗口的缩略图画面

关键字&#xff1a; capture minimized window window thumbnail IsIconic 问题背景 最小化的窗口&#xff0c;API GetClientRect 返回的窗口尺寸是0x0&#xff0c;故无法通过GetDCBitBlt捕获到窗口画面。 但是 Agora/zoom/tencentMeeting 都可以拿到最小化窗口的缩略图…

Python自动化必不可少的测试框架 — pytest

Python在测试圈的应用非常广泛&#xff0c;特别是在自动化测试以及测试开发的领域&#xff0c;其中在自动化测试中我们常用的测试框架是uniitest和pytest&#xff0c;本文将带领大家搭建以及熟悉pytest的使用。 既然有unittest那么为什么还要用pytest呢&#xff1f; 这是因为…

会议论文分享-Security22-状态感知符号执行

Ferry: State-Aware Symbolic Execution for Exploring State-Dependent Program Paths1.引言2.问题陈述与分析2.1.实现状态感知符号执行的挑战2.2.真实程序的特征2.3.Ferry的模型2.3.1.程序状态的定义2.3.2.状态描述变量的特征3.Design3.1.Overview of Ferry3.2.状态描述变量识…

CISCN(Web Ezpentest)GC、序列化、case when

目录 REGEXP的一个点&#xff08;正则&#xff09; like&#xff08;默认不区分大小写&#xff09; 当禁用了空格 regexp&#xff0c;like的区分大小写的使用方法 [CISCN 2022 初赛]ezpentest 卡点 2022 HFCTF babysql 最近又学到了一道新知识&#xff0c;case when的错…

Python|每日一练|排序|递归|链表|字符串|数组|动态规划|哈希表|单选记录:K 个一组翻转链表|括号生成|无重复字符的最长子串

1、K 个一组翻转链表&#xff08;递归&#xff0c;链表&#xff09; 给你一个链表&#xff0c;每 k 个节点一组进行翻转&#xff0c;请你返回翻转后的链表。 k 是一个正整数&#xff0c;它的值小于或等于链表的长度。 如果节点总数不是 k 的整数倍&#xff0c;那么请将最后剩…

kafka安装及使用

目录 1.单机部署 1.下载安装包 2.启动zookeeper服务 3.启动kafka broker服务 2.集群部署 1.下载安装包 2.修改zookeeper配置 3.修改kafka配置 4.在3台机器上启动zookepper 5.在3台机器上启动kafka 6.检查是否启动OK 3.使用 1.创建topic 2.查看kafka topic分区数 …

OpenFaaS介绍

FaaS 云计算时代出现了大量XaaS形式的概念&#xff0c;从IaaS(Infrastructure as a Service)、PaaS(Platform as a Service)、SaaS(Software as a Service)到容器云引领的CaaS(Containers as a Service)&#xff0c;再到火热的微服务架构&#xff0c;它们都在试着将各种软、硬…

通过Prowork每日自动提醒待处理工作任务

对于中小团队来说&#xff0c;由于不需要繁琐的流程和高频的异地沟通&#xff0c;需要一款更适合中小团队的日程和项目管理工具。而Prowork就是这样一款敏捷高效的协同平台。Prowork与以往各种项目管理⼯具最⼤的不同在于&#xff0c;其弱化流程和弱化权限的特性&#xff0c;不…