【必看】Vuex 与 Pinia 的设计实现对比

在进行前端项目开发时,状态管理始终是一个绕不开的话题,Vue 与 React 框架本身提供了一部分能力去解决这个问题。但是在开发大型应用时往往有其他考虑,比如需要更规范更完善的操作日志、集成在开发者工具中的时间旅行能力、服务端渲染等。本文以 Vue 框架为例,介绍 Vuex 与 Pinia 这两种状态管理工具在设计与实现上的区别。

Vue 状态管理

首先,先介绍一下 Vue 框架自身提供的状态管理的方式。

Vue 组件内主要涉及到状态、动作和视图三个组成部分。

在选项式 API 中通过 data 方法返回一个状态对象,通过 methods 方法设置修改状态的动作。

如果使用组合式 API + setup 语法糖,则是通过 reactive 方法生成状态,而动作只需要当做普通函数或者箭头函数进行定义即可。

选项式 API:

<script>
export default {
   
  data() {
     // 状态 state
    return {
   
      count: 0
    }
  },
  methods() {
    // 动作 action
    increment() {
   
      this.count++
    }
  }
}
</script>
// 视图 view
<template> {
   {
    count }} </template>

组合式 API + setup 语法糖:

<script setup lang="ts">
import {
    reactive } from 'Vue'
// 状态 state
const state = reactive({
   
  count: 0
})
// 动作 action
const increment = () => {
   
  state.count++
}
</script>
// 视图 view
<template> {
   {
    state.count }} </template>

在这里插入图片描述

视图由状态生成,操作可以修改状态。

如果可以将页面的某一部分单独抽离成与外界解耦的状态、视图、动作组成的独立个体,那么 Vue 提供的组件内的状态管理方式已经足够了。

但是开发中经常会遇到这两种情况:

  • 多个页面组件依赖于相同的状态。
  • 在多个页面组件内的不同交互行为需要修改同一个状态。

比如我们要做一个主题定制功能,需要在项目入口处获取接口中的颜色参数,然后在整个项目的很多页面都要使用到这个数据。

一种方法是使用 CSS 变量,在页面的最顶层的 root 元素上定义一些 CSS 变量,在 Sass 中使用 var() 初始化一个 Sass 变量,所有页面都引用这个变量即可。在项目入口处获取接口数据,需要手动去修改 root 元素上的 css 变量。

在 Vue 中,框架提供了一种 v-bind 的方式去编写 css,我们可以考虑将所有颜色配置存放在一个统一的 store 里面。

遇到这两种情况,通常我们会通过组件间通信的方式解决,比如:

  • 对于相邻的父子组件:props/emit
    • defineProps({})
    • defineEmits(['change', '...'])
  • 对于多层级嵌套:provide/inject
    • provide(name: string | symbol, value: any)
    • inject(name: string | symbol, defaultValue: any)

1、如果是相邻的父子组件之间通信,可以通过 props+emit 的方式,父组件通过子组件的 props 传入数据,在子组件内部通过 emit 方法触发父组件的一些方法。

在这里插入图片描述

2、如果不是直接相邻,而是中间相隔很多层的嵌套关系,那么可以使用 provide+inject 的方式,高层级的组件抛出状态和动作,低层级的组件接收使用数据和触发动作。

在这里插入图片描述

如果目标的两个组件并不在同一条组件链上,一种可能的解决方法是「状态提升」。

可以把共同的状态存储在二者的最小公共祖先组件上,然后再通过上述两种方式进行通信。

  • 前者:公共祖先组件存储状态,通过 props 逐级传递响应式状态以及其关联的操作到子组件。
  • 后者:公共祖先作为提供方,多个后代组件作为注入方获取数据以及操作数据。

后者编写代码更简洁,更不容易出错。

这样已经能够解决大多数场景的问题了,那么在框架之外的状态管理工具,到底能提供哪些与众不同的能力?

Vuex 与 Pinia 核心思想与用法

Flux 架构

Flux 是 Facebook 在构建大型 Web 应用程序时为了解决数据一致性问题而设计出的一种架构,它是一种描述状态管理的设计模式。绝大多数前端领域的状态管理工具都遵循这种架构,或者以它为参考原型。

Flux 架构主要有四个组成部分:

  • 📦 store:状态数据的存储管理中心,可以有多个,可以接受 action 做出响应。
  • 🖼 view:视图,根据 store 中的数据渲染生成页面,与 store 之间存在发布订阅关系。
  • 🛠 action:一种描述动作行为的数据对象,通常会包含动作类型 type 和需要传递的参数 payload 等属性。
  • 📮 dispatcher:调度器,接收 action 并分发至 store。

在这里插入图片描述

整个数据流动关系为:

1、view 视图中的交互行为会创建 action,交由 dispatcher 调度器。

2、dispatcher 接收到 action 后会分发至对应的 store。

3、store 接收到 action 后做出响应动作,并触发 change 事件,通知与其关联的 vie

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端开发小马哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值