前端文艺复兴:真的需要Pinia吗?

前言

说起Pinia,熟悉vue3开发的程序员肯定不会陌生,甚至被vue官方推荐取代vuex,成为vue全家桶之一。

疑惑

还记得之前用 vuex 时,更改state还分同步和异步(这里有尤雨溪的回答www.zhihu.com/question/48... ,面试还被问过为什么...,当时也是不太理解,觉得肯定有他的道理,谁知看了pinia后,更改state同步异步都可以......

我悟了,作者说啥都有他的道理

回到正题:但我们真的需要Pinia/Vuex吗?Pinia/Vuex解决了什么问题?没有Pinia/Vuex前我们是怎么做的呢,会有什么问题?

刨根

对于以上问题,以下是本人的一些思考(有不足之处,还望赐教🙏)

为什么需要Pinia,它解决了什么问题?先查下官网/别人怎么说;

网上很多是说,Pinia 是 Vue.js 的轻量级状态管理库

官方文档如下描述:

对于以上支撑观点,下面一个个来看,看下Pinia是否是必须的:

1. Pinia 是 Vue.js 的轻量级状态管理库

详阅vue官网关于状态管理 的文章,里面提到一个场景:多个组件共享一个共同的状态 时,用vue原生的能力实现有点麻烦,文章推荐以下方法,将公用的数据提取到全局,这样需要的组件可以直接引用:

js 复制代码
// store.js
import { reactive } from "vue";

export const store = reactive({
  count: 0,
  // ...
});
vue 复制代码
<!-- ComponentA.vue -->
<script setup>
import { store } from './store.js'
</script>

<template>From A: {{ store.count }}</template>
vue 复制代码
<!-- ComponentB.vue -->
<script setup>
import { store } from './store.js'
</script>

<template>From B: {{ store.count }}</template>

那我们先用这个简单的方法解决状态管理的问题,后面看下会遇到什么问题;

2. Devtools 支持(...)

不好意思,本人开发过好几个vue项目,从来没用过 vue devtools,都是console.log一把梭,目前感觉可以满足调试需要,这个在我这里就先跳过了,忽略!(用vue devtools很爽的可以评论分享下使用场景&经验,跪求🙏)

3. 热更新(不必重载页面即可修改 Store、开发时可保持当前的 State)

呃...,没看太懂这个场景,如果说是下面这种热更新,上面的简单方法也可以做到,而且严格上说这应该是构建工具提供的能力吧,像webpack hmr/vite hmr;

既然简单的方法也可以做到我理解的热更新,平时好像也没有这方面的困扰,先跳过,忽略!(有这方面需要的请分享下经验,跪求🙏)

4. 插件:可通过插件扩展 Pinia 功能

这个等需要用Pinia再考虑这个,先跳过,忽略!

5. 为 JS 开发者提供适当的 TypeScript 支持以及自动补全功能

呃呃,上面的简单方法也可以做到,而且ts声明更方便,如下:

ts 复制代码
// store.ts
import { reactive } from "vue";

interface IStore {
  count: number;
  // ...
}
export const store = reactive<IStore>({
  count: 0,
  // ...
});

有了ts声明后,自动补全是编辑器提供的功能,先跳过,忽略!

6. 支持服务端渲染

简单方案

先说上面简单的方法,用该方法会导致跨请求状态污染 问题;如下图,从技术上讲,我们可以在每个请求上重新初始化 store,

对于上图的 初始化 JavaScript 模块的成本可能很高 说法,我有点怀疑,因为 onMounted 或者 onUpdated 这样的生命周期钩子不会 在 SSR 期间被调用,而通常让 store 变大变复杂的更改是在 onMounted 里获取数据接口回调里执行的,默认 store 就是一堆初始化的数据声明而已吧,所以在 SSR 里,为了解决 跨请求状态污染 问题,在每个请求上重新初始化 store 成本我感觉不高(个人观点,还望指教🙏),适配ssr修改如下:

js 复制代码
// store.js
import { reactive } from "vue";

export let store = createStore();
export const createStore = ()=>{
  return reactive({
    count: 0,
    // ...
  });
}
js 复制代码
// app.js (在服务端和客户端间共享)
import { createSSRApp } from 'vue'
import { createStore, store } from './store.js'

// 每次请求时调用
export function createApp() {
  // 对每个请求都重新初始化 store 实例
  store = createStore();
  
  const app = createSSRApp(/* ... */)
  return { app }
}

Pinia方案

pinia.vuejs.org/zh/ssr/

经过对比,简单方法个人认为也可以支持服务端渲染,且没有额外的概念、学习成本!

结论

据以上分析,我发现并没有必须用Pinia的理由,虽然其中第一点和第六点在实战中可能会需要,但用简单方法也可以解决且没有很麻烦。所以,如果为了解决这两个问题而引入一堆概念、用法,从而增大心智负担/学习成本,我觉得性价比不高,且容易居高而忘了事情本质,糊里糊涂地跟着用而已,殊不知有更简单直接的方法!全部代码如下:

只需要状态管理

js 复制代码
// store.js
import { reactive } from "vue";

export const store = reactive({
  count: 0,
  // ...
});

需要支持服务端渲染

js 复制代码
// store.js
import { reactive } from "vue";

export let store = createStore();
export const createStore = ()=>{
  return reactive({
    count: 0,
    // ...
  });
}
js 复制代码
// app.js (在服务端和客户端间共享)
import { createSSRApp } from 'vue'
import { createStore, store } from './store.js'

// 每次请求时调用
export function createApp() {
  // 对每个请求都重新初始化 store 实例
  store = createStore();
  
  const app = createSSRApp(/* ... */)
  return { app }
}

其他

简单方法不好维护

有人拿出官方文档说上面简单的方法从长远来看不好维护。

但本人很反感这种没有事实依据的论点,有点 专家说 那味;有点杞人忧天,过度优化的感觉;我更推崇的是一步步深入,用事实说话,举例说明'在xx情况下,你看很难维护了吧',这会令我信服且更加理解。

刷新页面store数据丢失

按我理解,这只是一个现象,重要的是会造成什么问题 。网上很多文章只根据现象就开始提解决方法了,比如把整个 store 缓存到 sessionStorage 里,或者 vuex/pinia 直接提供了持久化的插件。但我总感觉没触到事情本质,于是搜一下具体的场景:

    1. 有人说登录状态信息,刷新后需要保持登录状态
    1. 找不到其他场景了...(有补充的朋友请以案例说明,跪求🙏)

那针对以上场景,简单来做不是哪个需要缓存就缓存哪个吗,比如登录信息需要缓存:

js 复制代码
import { store } from './store.js'

// ... 
window.onbeforeunload = () => {
  // 用localStorage/sessionStorage/cookie/indexDB 根据自己需要判断
  localStorage.setItem("__loginInfo__", JSON.stringify(store.loginInfo));
}
js 复制代码
// main.js
import { store } from './store.js'

// ... 
const loginInfo = localStorage.getItem("__loginInfo__");
if (loginInfo) {
  store.loginInfo = JSON.parse(loginInfo);
}
// ...

所以,我理解这种持久化问题和状态管理不应该放在一起讨论,我建议是根据场景,按需缓存

最后

纸上得来终觉浅,绝知此事要躬行

很多时候感觉在前端学不动了,其中原因之一必有:概念太多、轮子太多、技术更新太快,需要不断学习......

但个人感觉很多概念都是莫须有的,利用原生知识亦可解决,而无需增加心智负担,但要识别这些信息谈何容易啊,希望我们始终保留对问题本质的好奇吧。最后分享一句很喜欢的编程哲学语句:

Keep it simple, stupid (KISS)

相关推荐
sunbyte41 分钟前
50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | Expanding Cards (展开式卡片)
javascript·vue.js·ecmascript
重生之后端学习2 小时前
02-前端Web开发(JS+Vue+Ajax)
java·开发语言·前端·javascript·vue.js
黄鹂绿柳5 小时前
Vue+Vite学习笔记
vue.js·笔记·学习
来自星星的坤5 小时前
【Vue 3 + Vue Router 4】如何正确重置路由实例(resetRouter)——避免“VueRouter is not defined”错误
前端·javascript·vue.js
清风细雨_林木木11 小时前
Vue 中生成源码映射文件,配置 map
前端·javascript·vue.js
霸王蟹12 小时前
React中巧妙使用异步组件Suspense优化页面性能。
前端·笔记·学习·react.js·前端框架
霸王蟹13 小时前
React 19版本refs也支持清理函数了。
前端·javascript·笔记·react.js·前端框架·ts
繁依Fanyi13 小时前
ColorAid —— 一个面向设计师的色盲模拟工具开发记
开发语言·前端·vue.js·编辑器·codebuddy首席试玩官
codelxy13 小时前
vue引用cesium,解决“Not allowed to load local resource”报错
javascript·vue.js
Zww089114 小时前
el-dialog鼠标在遮罩层松开会意外关闭,教程图文并茂
javascript·vue.js·计算机外设