关于 Vue 的状态管理的一点困惑

2022-09-15 18:10:57 +08:00
 shintendo

背景:Vue 版本 2.7 ,2 到 3 人的小项目,不使用 composition api ,不使用 SSR

目的:只是想要响应式的全局变量

关于 Vuex ,一个常见的说法是"大项目更需要,小项目不必强行用",我的问题是:

1.Pinia 仍然适用这个说法吗?还是说 Pinia 因为更简单所以无脑上?

2.如果嫌啰嗦不想用 Vuex 的话,可以用什么?很多地方包括 Vue 2 的文档提到 Event Bus 模式,但我也看到很多博客和论坛包括 Vue 的 Core Team 开发者都强烈反对这一模式。其中一个原因是说,Event Bus 没有一个中心化的 state ,而是用事件的发布 /订阅来同步数据,因此难以维护。

问题来了,Event Bus 为什么不用中心化的 state ?或者说,为什么不是 Data Bus 而是 Event Bus ?我的意思是:

// bus.js
const bus = new Vue({
  data () {
    count: 1
  }
})
Vue.prototype.$bus = bus

// App.vue
<template>
  <div>
    {{ $bus.count }}
    <button @click="$bus.count++">Add</button>
  </div>
</template>

这样写我试了一下是可以的,数据也是响应式的,我觉得似乎是一个很自然的想法?但是为什么搜不到任何相关的讨论,甚至不知道这个模式有没有名字(类似 Event Bus )?还是说有什么我没看到的原因导致不能这样写?

问的有点乱,简单说就是用一个 Vue 实例来充当 Store 是不是反模式?

3689 次点击
所在节点    Vue.js
26 条回复
thinkershare
2022-09-15 18:21:29 +08:00
Vue 实例对象不是用来干这件事的, 另外响应式对象的确可用达到你的目的
使用 Vuex 是因为它有其它用途, 需要一个全局的状态管理器, 而且这个状态管理器需要可观察性(这一点非常重要, 也是它为什么设计的如此难用的重要原因).
Pinia 基本可用无脑上.
EventBus 在前端不合适的原因你已经说了, 因为它需要数据同步.
throns
2022-09-15 18:23:29 +08:00
你甚至可以把你的状态保存到 window 对象来存入,还有很多别的方式莱实现状态共享。为什么要有专门做状态管理的库呢?
sunwang
2022-09-15 18:25:12 +08:00
我的理解是区别不大,如果使用 Event Bus 的话是没有一个专门的文件去维护全局状态的,全部操作都要放到监听函数里。如果使用 Vuex 的话,是会有一个专门的文件去管理,理论上是更清晰的。从实现上其实没区别,Vuex 内部也会实例化一个 vm 用来做响应式,个人拙见。
sechi
2022-09-15 18:26:20 +08:00
可以但没必要,这写法太不规范了。现在你们两三个人写项目还比较好沟通,如果以后加人呢?如果以后换人维护呢?接手项目的人估计第一反应是先骂一句。用了 pinia 起码人家稳定维护,还有完整的文档,况且它的体量又不大,何乐而不为呢?
gouflv
2022-09-15 18:38:38 +08:00
vue 文档里不是说了简单 store 的模式吗,只是大部分人忽略了而已
wu67
2022-09-15 18:42:53 +08:00
别听那些文章瞎说, 有状态共享的需求, 就直接上. 除非你确定你的项目写完就扔, 不再维护, 不然迟早会出现第二个、第三个要共享的状态数据, 那为什么不用 vuex
KouShuiYu
2022-09-15 18:56:11 +08:00
你问的在官方文档里都有
https://v2.cn.vuejs.org/v2/guide/state-management.html


既然用 Vue 2.7 响应式的全局变量推荐的方式是这种, 比 Pinia 简单多了
```
import { ref } from "vue";

export const count = ref(1);
export const countAdd = () => count.value++;
```

那么 什么时候用 Pinia 呢?
需要用到后端 SSR 时,原因: https://pinia.vuejs.org/introduction.html#why-should-i-use-pinia
fool079
2022-09-15 19:14:52 +08:00
其实你这么写已经是一个简单的 vuex 了~
zcf0508
2022-09-15 19:16:17 +08:00
在用 hami-vuex ,api 比较友好
HiCode
2022-09-15 19:21:10 +08:00
Vue 文档有简单 store 的模式,小型项目使用这个模式没什么问题,我基本就是用这个。很多项目其实用不到 Vuex 。
Vegetable
2022-09-15 19:24:40 +08:00
这不是和 const bus = reactive({count:1}) 一样吗
toesbieya
2022-09-15 20:47:12 +08:00
vuex 太垃圾了,语法提示 P 都没有,取个值都罗里吧嗦,直接 reactive 一把梭
w88975
2022-09-15 20:55:40 +08:00
用了下 pinia ,感觉没有 mobx 那套用起顺手,于是用 reactive 自己撸了
sjhhjx0122
2022-09-15 23:09:49 +08:00
实在烦就用 reactive 从顶部注入一下就好了最简单了
angrylid
2022-09-15 23:23:11 +08:00
其实流行的库和框架就相当于“制式武器”的东西。
shakukansp
2022-09-16 01:17:07 +08:00
vuex 里存的东西很少,都是全局要用的用户信息、全局视图状态啥的
别的页面都是局部的业务状态共享

项目还用 vuex 存全部的业务状态,说明你这项目页面还不够多,业务类型还不够多
YuTengjing
2022-09-16 02:40:27 +08:00
1. pinia 适用,状态管理工具本质上大同小异
2. 不想要用可以,那你应该没法像 pinia 那样使用 vue devtools 集成,简单的场景可以用状态提升或者 provide/inject ,vue3 直接导出一个 ref 就可以了
3. 本质上状态管理工具和你自己写的这个例子一样底层都是使用发布订阅,只不过功能更丰富,更好维护。背后的生态才是更重要的,比如你想做 state 持久化,vuex 可以直接用 https://github.com/robinvdvleuten/vuex-persistedstate 。那这时候你要做持久化,如果之前没用第三方框架自己手撸持久化吗?
4. 如果这可以满足你的需求直接就这样用就完事了,你觉得很自然?我觉得一点都不自然。你写的代码有哪里可以看出官方是想让你这么用的,Vue 构造器是来用来构建 VM 实例的。如果要看着像是用来构造响应式数据的为什么不直接叫 Reactive 而要叫 Vue 。只不过它在这里刚好能实现你想要的响应式的数据罢了。
yaphets666
2022-09-16 09:42:48 +08:00
一个常见的说法是"大项目更需要,小项目不必强行用"

这谁说的? vue 要的就是简单,谁都能看懂,所以工具就要统一,就用 vuex
yaphets666
2022-09-16 09:44:28 +08:00
写什么东西要有什么东西的思维,要入乡随俗,别拿锄头吃饭,也别拿筷子去犁地。反面例子就是早期版本的 AntDesign-Vue
Terry05
2022-09-16 09:49:10 +08:00
在 vue3 的官方文档里,对于状态管理的部分,开篇就介绍了可以使用 reactive 来创建一个简易的响应式状态对象

// /store/index.js
export cosnt store = reactive({ count: 0 })

// 任意位置
import { store } from '@/store'
console.log(store.count)

使用 reactive 来作为组件级别的状态管理非常好用,我自己在 2.7 和 3.x 上多了它以后,对于 vuex / pinia 的使用就大幅减少,而是以功能模块为单位,使用 reactive 的方式来管理、维护和应用模块内的状态,只是全局的状态,比如用户、权限、模块、当前各种系统状态这类系统级的状态还是应该由 vuex / pinia 来管理比较合适

当然,在使用了 reactive 后,provide / inject 就几乎没再使用过了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/880332

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX