vuex的命名空间有哪些_Vue 3 带来的 Vuex 的替代方案

一、前言

就像是 React 社区在 HOOK API 出现后很快就使用 useReducer、useContext 代替了 Redux 进行状态管理一样。Vue3 也是时候抛弃 Vuex 进行状态管理了。

在考虑为什么要抛弃 Vuex 之前,我们先来想一下为什么要引入 Vuex?

Vuex 实际上解决的问题是「组件间传递对象」的问题:

在传统的方式里,我们如果要把一个对象从父组件传递到子组件,要使用 prop 进行传递。

如果组件间不是直接的「父子关系」的话(如「爷孙关系」),传递对象的过程要经过整颗组件树————这让我们的代码变得很丑陋,提高了相当多的复杂度。

我们引入 Vuex 就是为了提供一个统一管理组件状态的地方,来让我们的组件之间可以简单的传递对象。

但是引入 Vuex 的本质原因还是:降低代码的复杂度

但是 Vuex 陡峭的学习曲线,令人费解的 Getter、Module、Store、Mutation、Action 等概念,又引入了新的代码复杂度,新的心智负担。

当我真正掌握了它的时候,我并没有惊呼,而是对其产生了深深的排斥。

所以,当现在 Vue3 到来,有了更新、更轻量的依赖注入工具 provide、inject 函数,我们有什么道理不像隔壁的 React 社区学习————用 useReducer、useContext (provide、inject)代替 Redux(Vuex)呢?


二、关于 Vue3 与 Vue Composition API

目前 Vue 3 还处于 Alpha 版本,但是我们已经可以通过使用 @vue-composition 来提前在 Vue2 环境下体验 Vue3 的新特性了。

  • vue 3 的 Github:https://github.com/vuejs/vue-next
  • vue-composition 的 Github:https://github.com/vuejs/composition-api
  • vue-composition 的使用文档:https://vue-composition-api-rfc.netlify.com/api.html

vue-composition 提供了类似 React Hook 的能力,将 Vue 的抽象层级从「组件级(Component)」降低为「函数级(Function)」。

用了将近一周的时间,说句实话,我感觉到非常的兴奋!

Vue Composition API 的建议学习路线

如果想学习 vue-composition 的同学,可以点击上面的 vue-composition 的使用文档进行学习,学习路线建议如下:

  1. 在 vue2.0 项目中安装 composition-api(请查看 composition-api 的Github)
  2. 学习 composition-api 的 API Reference 文档
  3. 在 vue2.0 项目中使用 composition-api + typescript 重构(推荐使用 typescript 的原因是,都 2020 年了)
  4. 学习 composition-api 的 RFC 文档

三、Vuex 是什么?

打开 Vuex 的官方网站,我们可以看到这样一段描述:

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 也集成到了 Vue 的官方调试工具 devtools extension,提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。

我们来画一下重点,看看 Vuex 提供了什么能力:

  1. 集中式存储管理应用的「所有组件」的「状态」
  2. 保证状态以「可预测」的方式「发生变化」
  3. 与调试工具集成,提供功能:time-travel、状态快照导入导出

我们仔细的看一下,然后准备去设计一个新的状态管理模式

第一条:集中式存储管理「所有组件」的「状态」

请注意,这里它并不是要去管理「所有组件」的「所有状态」———— 也就是说我们每个组件中还是可以有自己的「私有状态」的。

这很好理解:
比如在「登录注册页面」中我们的「短信验证码计时器」的状态很明显就是一个「私有状态」。

那我们要解决的就是集中式存储管理这件事情了,我认为该难点在于:

  1. 需要维护「公共状态」的「单例」性(由于 Chrome 使用的是「标记清除」的垃圾回收策略,而不是「引用计数」的垃圾回收策略,所以我们不用担心在 Vue 的生命周期内变量被 GC 回收的问题)
  2. 需要维护「公共状态」的「命名」全局可见
  3. 需要维护「公共状态」全局可「访问」

第二条:保证状态以「可预测」的方式「发生变化」

需要解决的难点就是,状态的变化可以被追溯到:

即:「哪个组件」改变了「什么状态」

第三条:时间旅行与状态快照导入导出

本条的难点在于——是否全局状态就是一个 Vue APP 的快照?

以及是否有一个工具配合你做调试。


四、provide、inject 是什么?

provide、inject 是 vue-composition-api 的一个新功能:依赖注入功能

import { provide, inject } from 'vue'const ThemeSymbol = Symbol()const Ancestor = {setup() {provide(ThemeSymbol, 'dark')}
}const Descendent = {setup() {const theme = inject(ThemeSymbol, 'light' /* optional default value */)return {theme}}
}

这是怎么注入的呢?我们还是看图来说话:

91de64c3fcd86b23b4d0ae3e1da28ef4.png

我们都知道 Vue 是一颗「组件树」,我们只要保证是「父节点」 provide,那么它的「子节点」就一定可以通过 inject 获取到。

举例:

  • A provide,B 可以 inject,C 可以 inject,D 可以 inject
  • B provide,D 可以 inject
  • D provide,没有其它节点可以 inject
  • C provide,没有其它节点可以 inject

五、我们结合一下 Vuex 的特点和 provide、inject 的特性来看,新的状态管理应该具有哪些特点

5.1 声明一次,全局可访问

为了实现这样子的特点,我们就需要将「需要共享的状态」事先在我们 Vue 的根节点 App.vue 中通过 provide 声明好了。

而「单例」的需求也在这里得到解决——我们的状态不会被创建多次。

5.2 全局可访问「公共状态」的「命名」

全局可访问即全局可导入,我们仅需要把「公共状态」的「命名」放在一个单一的文件中即可:

// src/store/store.ts
const temporaryPlanList = Symbol()
const dailyPlanList = Symbol()
export default {temporaryPlanList,dailyPlanList
}

然后再在需要访问的地方导入:比如 App.vue 中 provide

// src/App.vue
<script lang="ts">
import Store from "./store/store"import { defineComponent, provide, ref } from "@vue/composition-api"
export default defineComponent({setup() {provide(Store.temporaryPlanList, ref([]))provide(Store.dailyPlanList, ref([]))}
})
</script>

比如 Plan.vue 中 inject(Plan.vue 是 App.vue 的子节点)

// src/views/Plan.vue
<script lang="ts">
import Store from "./store/store"import { defineComponent, provide, ref } from "@vue/composition-api"
export default defineComponent({setup() {const temporaryPlanList = inject(Store.temporaryPlanList)const dailyPlanList = inject(Store.dailyPlanList)}
})
</script>

5.3 保证「状态」以可预测的方式发生变化

其实.....就是要多设置一个 setter 而已。

就像是 Vuex 中 Store 中存储的状态要靠 mutation 提交才可以更改。

但是这真的有用吗?不是脱了裤子放屁吗?

反正我认为是多此一举,还不如就是直接修改全局变量的状态。

5.4 时间旅行与应用快照

这点需要调试工具配合,目前来看是无法用 inject、provide 替代了。

六、参考文献

https://blog.logrocket.com/use-hooks-and-context-not-react-and-redux/​blog.logrocket.com

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

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

相关文章

C# Task异步编程

1、不适用异步的示例 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Threading; using System.Net; using System.Diagnostics;namespace ConsoleApplication1 {class MyDownloadStrin…

人形图案c语言程序_最多 280 字符,你能用 Basic 玩出哪些花样程序来?

(给程序员的那些事加星标)转自&#xff1a;机器之心【导读】&#xff1a;推特与计算机能擦出什么样的火花呢&#xff1f;大多数人可能就想到在计算机上发推特呗。但是&#xff0c;有人就不这么想。酷爱计算机演进史和推特的 Dominic Pajak 创建了 BBC Micro Bot&#xff0c;它能…

???--???二进制变换

题意 &#xff1a; 定义两种变换 1 &#xff1a; i i - 1 2 &#xff1a; i i - lowbit (i) 定义函数Calc(i,j)为二进制意义下 i 变换到 j 的最小步数。 给你一个二进制整数 n&#xff0c;要求 sigma {(i 1 -> n) sigma {(j 0 -> i - 1) Calc (i,j)}} 数据范围 : 令…

C# 派生类的构造函数

假定没有为任何类定义任何显式的构造函数,这样编译器就会为所有的类提供默认的初始化构 造函数,在后台会进行许多操作,但编译器可以很好地解决类的层次结构中的所有问题,每个类中 的每个字段都会初始化为对应的默认值。但在添加了一个我们自己的构造函数后,就要通过派生类 的层…

js 获取url问号前_PHP获取指定网页的HTML代码并执行输出

PHP获取指定网页的HTML代码并执行输出&#xff0c;这个方法主要是将所要或取目标的URL地址的网站中获取相关内容到自己的网页中。代码如下&#xff1a;<?php $srcurl "所要截取目标的URL地址"; $handle fopen($srcurl,"rb"); $content fread($handl…

AD16画线时如何切换90°、45°、任意角度画线模式

在绘图界面选择画线后&#xff0c;使用“shift空格”可切换不同的画线模式。切换过程中会有90模式、45度模式、任意角度模式等&#xff0c;在这些模式中可使用空格键在进行细分切换。 1、90模式 2、45模式 3、任意模式

1200兆路由器网速_如何选购路由器才能发挥宽带的网速?

很多人多少都会遇到家里宽带网速慢的时候&#xff0c;家中明明是光纤宽带&#xff0c;可是网速却没有想象中的那么快&#xff1f;尤其是宽带的带宽升级到100M、200M、500M的时候&#xff0c;感觉跟没有提速一样。也许你家的路由器该换新啦&#xff01;那么&#xff0c;想要选购…

C# 静态类

------《C#高级编程》第7版

vant实现下拉刷新和上拉加载_微信小程序 - 实现下拉刷新、上拉加载

在小程序开发中使用下拉刷新和上拉加载非常多&#xff0c;比如常用的展示型首页&#xff0c;而实现这个功能有两种形式&#xff0c;第一种是使用 scroll-view 组件&#xff0c;第二种是不使用 scroll-view 组件而让整个页面刷新&#xff0c;那就分别都在此简单分享下。方法一在…

mapper同时添加数据只能添加一条_springcloud项目搭建第二节:eureka+数据库

在上一节搭建的项目基础上&#xff0c;在父项目spring-cloud的pom文件中添加mapper启动器和mysql驱动的配置&#xff0c;如果项目中使用lombok也可以引用&#xff0c;这里需要注意的是lombok引用的配置不在dependencyManagement结构中&#xff0c;这时为什么呢&#xff0c;因为…

在centOS7.2里安装virtualenv和flask

1&#xff09; 安装pip工具 #wget https://bootstrap.pypa.io/get-pip.py #python get-pip.py 2&#xff09; 安装virtualenv&#xff0c;并创建一个开发环境 #pip install virtualenv #mkdir rongtangzi #创建一个项目 #cd rongtangzi #virtualenv env1 #…

事务连接中断_一文搞懂分布式事务-CAP理论

互联网系统中&#xff0c;分布式事务是无法避免的&#xff0c;目前多数解决方案是BASE理论&#xff0c;最终一致性&#xff0c;结合事务补偿。1.什么是CAP理论。CAP理论&#xff0c;又称为布鲁尔定理&#xff0c;是加州大学伯克利分校的计算机科学家埃里克.布鲁尔(Eric Brewer)…

C# WinForm中获取当前程序运行目录的方法

C# WinForm中获取当前程序运行目录的方法&#xff1a; “AppDomain.CurrentDomain.BaseDirectory”:获取当前应用程序所在目录的路径&#xff0c;最后包含“\”&#xff1b;“System.Threading.Thread.GetDomain().BaseDirectory”:获取当前应用程序所在目录的路径&#xff0c…

网络攻防 第四周学习总结

教材学习内容总结 第四章主要介绍了网络嗅探和协议分析网络嗅探是一种常用的窃听技术&#xff0c;它利用计算机的网络接口截获目的地为其他计算机的数据报文&#xff0c;以监听数据流中所包含的用户账户密码或私密信息等。 网络嗅探具有很强的隐蔽性&#xff0c;往往让网络信息…

获取内存_如何获取一个进程所占用的内存

推荐观看&#xff1a;BATJ面试官最喜欢问的&#xff1a;多线程、线程并发面试题详解&#xff08;volatileThreadLocalSleep&#xff09;_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili​www.bilibili.com通过 ps 可以获知一个进程所占用的内存$ ps -O rss -p 3506PID RSS S TTY …

中的ama格式_想发SCI?期刊引用格式选好了没?

我~芳~老师~又回来开坑了哈哈哈哈哈&#xff01;&#xff01;&#xff01;对于一心想要冲向SCI、EI顶峰&#xff0c;拉都拉不住的同学来说&#xff0c;我们需要把论文中的每一个细节都抠得死死的。合乎规范地引用科学期刊&#xff08;Scientific Journal&#xff09;绝对是最重…

伺服怎么接单相220伏_乐利网带你认识伺服电机及工作原理

什么是伺服电机&#xff0c;应该听过人的不少&#xff0c;没听过的也占不少数&#xff0c;其实&#xff0c;伺服电机是指在伺服系统中控制机械元件运转的发动机&#xff0c;是一种补助马达间接变速装置。伺服电机可使控制速度&#xff0c;位置精度非常准确&#xff0c;可以将电…

插入始终是1_OneNote使用小记(1)——针对PPT做笔记及最合适的PPT插入方式

本人经常使用OneNote进行上课笔记的记录&#xff0c;本文大概总结一下我是如何在上课时针对PPT进行笔记记录的&#xff0c;以及非常重要的PPT插入所占空间的问题。设备&#xff1a;普通笔记本电脑&#xff0c;无触控&#xff0c;故不使用绘图功能软件&#xff1a;OneNote2016&a…

有效数据外含有额外数据_Excel|应用数据有效性规范数据录入

【问题】EXCEL输入数据时&#xff0c;经常会输入不规范或者无效的数据&#xff0c;对数据的统计工作带来很大的麻烦。数据验证能够建立特定的规则&#xff0c;限制单元格可以输入的内容&#xff0c;从而规范数据输入&#xff0c;提高数据统计与分析效率。数据验证&#xff0c;在…

怎么实现hover_web前端CSS实现一个粒子动效的按钮

按钮(button)可能是网页中最常见的组件之一了&#xff0c;大部分都平淡无奇&#xff0c;如果你碰到的是一个这样的按钮&#xff0c;会不会忍不住多点几次呢&#xff1f;通常这类效果第一反应可能就是借助canvas了&#xff0c;比如下面这个案例点击预览(建议去codepen原链接点击…