Vue项目开发过程中,该如何维护全局状态?

2023-02-17 15:02:44 浏览数 (2)

全局状态

什么是状态?在代码的世界里,状态就是指数据,简单的理解:你现在的情绪状态是怎样的? “高兴”,“悲伤”,这就是描述你当前情绪状态的数据。

抽象到一个描述用户的Vue组件,当前登录的用户的头像和昵称,就是这个组件的状态(数据);

1.全局状态

从字面意思理解就是,在系统任意地方都可以调用的数据(类似全局变量的概念)。

2.全局变量

全局变量,一般特指系统内任意代码位置都可以调用的变量;

JS有很多实现全局变量,或者类似全局变量的方法:传统的直接在window对象上定义、AMD模块化时在模块内定义然后将模块对象暴露给window,Es6下操作公共的模块;

现在是Es6的时代,所以我们讨论一下Es6的模块(JS至今的模块化规范都有这些特性);

  1. 模块是一个局部作用域,通过export向外暴露接口;
  2. 模块在运行时只会初始化一次,在不同地方import引入的都是同一个模块对象
  3. 模块有着闭包的一些特性。

所以通过模块去实现易于管理的全局变量,是非常容易的。

如何选择

Vue拥有Vuex、pinia两款非常优秀的全局状态管理器,在项目开发中基本是标配了。自从有了它们之后,我们习惯性的将所有全局状态都通过它们来组织使用。

观点

需要响应式的变量用全局状态管理器、不需要响应式的用模块封装;

1.避免过度使用?

先来看看Vuex官网的说明:

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。这个状态自管理应用包含以下几个部分:

  • 状态,驱动应用的数据源;
  • 视图,以声明方式将状态映射到视图;
  • 操作,响应在视图上的用户输入导致的状态变化。

可以看出vuex主要是为了更加友好的管理需要全局响应式的数据,通过它定义的所有数据,都会进行数据代理;

在实际的业务中,有时候我们需要的只是一个全局变量,并不需要它具有响应式的特性。在这种情况下是否还要通过Pinia、Vuex来管理呢?

2.实际案例

假设有一个低代码平台的页面编辑器,需要实现修改后可以撤回,撤回后可以恢复的功能;

页面组成如下:

  • 左侧组件选取
  • 中间组件根据操作实时更新
  • 右侧编辑插入的组件的状态
2.1 总结
  1. 正在被编辑的页面,它的状态在当前页面是页面上所有组件共享(新增、修改、展示)的;并且是需要响应式(修改后实时更新);
  2. 用户的每一次修改都需要记录操作前的完整状态(快照);

对于这个修改、撤回的功能,我们可以单独拎出来,作为一个独立模块,而不是通过全局状态管理器,分析:

  1. 每一次保存的快照是不需要响应式特性的;
  2. 需要在任意地方都可以调用;
2.2 实现,拆分,模块组成
  1. 一个数组,用于保存每次产生变化的完整快照;
  2. 一个监视属性,监视全局状态管理内代表页面状态的那个对象;
  3. 一个保存快照的方法
  4. 一个定义保存多少次修改的变量;
  5. 一个指向指定快照的指针变量;
  6. 向外暴露一个撤回(将指针指向的快照推回全局状态管理器)方法;
  7. 向外暴露一个恢复(将指针指向的快照的前一个推回全局状态管理器)方法;

条件:

  1. 撤回时状态指针向前(小一点的索引)移动;
  2. 恢复时状态指针向后(大一点的索引)移动;
  3. 发生正常修改时指针执行最后一个索引;
  4. 撤回和恢复时,标记不需要记录快照,操作完成后,watch重置这个标记。
  5. 保存快照之前,数量达到上限时,shift第一个快照后再添加。
2.3 最后

当页面状态比较多的时候,通过上面的方式进行实现,会减少很多用不到的get、set,并且易用性、可维护性也是不差的;相信类似的需求场景还有很多,从这个角度来看,还是具有一定参考价值的。

本文只是个人观点,不具有通用性,仅供参考;

0 人点赞