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

news2024/10/7 10:24:11

前言

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

疑惑

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

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

刨根

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

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

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

官方文档如下描述:

image.png

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

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

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

// store.js
import { reactive } from "vue";

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

<template>From A: {{ store.count }}</template>
<!-- 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;

test.gif

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

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

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

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

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

// store.ts
import { reactive } from "vue";

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

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

6. 支持服务端渲染

简单方案

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

image.png

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

// store.js
import { reactive } from "vue";

export let store = createStore();
export const createStore = ()=>{
  return reactive({
    count: 0,
    // ...
  });
}
// 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 的理由,虽然其中第一点和第六点在实战中可能会需要,但用简单方法也可以解决且没有很麻烦。所以,如果为了解决这两个问题而引入一堆概念、用法,从而增大心智负担/学习成本,我觉得性价比不高,且容易居高而忘了事情本质,糊里糊涂地跟着用而已,殊不知有更简单直接的方法!全部代码如下:

只需要状态管理

// store.js
import { reactive } from "vue";

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

需要支持服务端渲染

// store.js
import { reactive } from "vue";

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

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

  const app = createSSRApp(/* ... */)
  return { app }
}

其他

简单方法不好维护

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

image.png

长远来看应该是数据量变多会导致不好维护吧,但随着数据量增多,我们把 store 分模块不就行了,对于每个独立小模块,还是一如开始,例如:

// store.js
import { reactive } from "vue";

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

// 或者直接铺平
export const moduleAStore = reactive({
  count: 0,
  // ...
});
export const moduleBStore = reactive({
  count: 0,
  // ...
});

// 或者分文件模块
// ...

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

刷新页面 store 数据丢失

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

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

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

import { store } from './store.js'

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

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

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

最后

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

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

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

Keep it simple, stupid (KISS)

2023.12.6 更新

一一看了大家的评论,下面列下我认同的文中简单方案的缺点:

  1. 如果有多处改变了store.xx,想要查找特定一次 store.xx 在哪里变更会比较麻烦;如果用pinia的话,改变 store.xx 有统一的入口,这时在入口处打个断点,根据调用盏可以快速知道是哪里变更了 store.xx

最后

欢迎关注"所谓前端"微信公众号,大家一起交流
点击扫码关注

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

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

相关文章

【实训】网络规划与部署实训

一 实训目的及意义 本周实训主要是了解网络规划与部署&#xff0c;熟悉三大厂商华为、思科、锐捷交换机路由器以及相关协议的原理和配置&#xff0c;提高学生的动手能力和分析规划部署能力。 实训主要针对计算机网络系统集成的设计与实现的实际训练&#xff0c;着重锻炼学生熟练…

【数据结构]排序算法之插入排序、希尔排序和选择排序

简单不先于复杂&#xff0c;而是在复杂之后。 文章目录 1. 排序的概念及其运用1.1 排序的概念1.2 排序运用1.3 常见的排序算法 2. 常见排序算法的实现2.1 插入排序2.1.1 基本思想2.1.2 直接插入排序2.1.3 希尔排序&#xff08;缩小增量排序&#xff09; 2.2. 选择排序2.2.1 基本…

重写Sylar基于协程的服务器(6、HOOK模块的设计)

重写Sylar基于协程的服务器&#xff08;6、HOOK模块的设计&#xff09; 重写Sylar基于协程的服务器系列&#xff1a; 重写Sylar基于协程的服务器&#xff08;0、搭建开发环境以及项目框架 || 下载编译简化版Sylar&#xff09; 重写Sylar基于协程的服务器&#xff08;1、日志模…

【STM32+HAL库+CubeMX】UART轮询收发、中断收发、DMA收发方法及空闲中断详解

&#xff08;转载&#xff09;原文链接&#xff1a;https://blog.csdn.net/qq_39344192/article/details/131470735 1. 什么是UART&#xff1f; UART是一种异步串行通信接口&#xff0c;常用于通过串口与外部设备进行通信。它通过发送和接收数据帧来实现数据传输&#xff0c;使…

ROS2 Humble学习笔记 (2)

本文发表于个人的github pages。因csdn本身显示插件和转载过程中导致显示不太友好。建议大家阅读原文。想查看完整内容&#xff0c;请移步到ROS2 Humble学习笔记2。 本文篇幅较长&#xff0c;可抽空按照章节阅读。本文只作为对入门教程的一种浮现和提升。 一、前言 在上一篇…

项目02《游戏-08-开发》Unity3D

基于 项目02《游戏-07-开发》Unity3D &#xff0c; 本次任务做物品相互与详情的功能&#xff0c; 首先要做 点击相应&#xff0c; 接下来用接口实现点击相应事件&#xff0c;具体到代码中&#xff0c;我们找到需要响应鼠标事件的对象&#xff0c; 双击PackageCell…

数据结构与算法:图论(邻接表板子+BFS宽搜、DFS深搜+拓扑排序板子+最小生成树MST的Prim算法、Kruskal算法、Dijkstra算法)

前言 图的难点主要在于图的表达形式非常多&#xff0c;即数据结构实现的形式很多。算法本身不是很难理解。所以建议精通一种数据结构后遇到相关题写个转换数据结构的接口&#xff0c;再套自己的板子。 邻接表板子&#xff08;图的定义和生成&#xff09; public class Graph…

c语言实现greedy snake(贪吃蛇)

##第一个小项目 大一学生寒假项目 最终实现效果如图 一.以C语言实现个人小项目 在我们快速学完了一个高级编程语言&#xff0c;就应该写一个小项目来加以巩固自己的学习成果。 所以今天&#xff0c;我们来尝试写一写greedy snake&#xff0c;对于大学生来说也是可以加强能…

超时引发的牛角尖二(hystrix中的超时)

至今我都清楚记得自己负责的系统请求云上关联系统时所报的异常信息。为了解决这个异常&#xff0c;我坚持让这个关联系统的负责人查看&#xff0c;并且毫不顾忌他的嘲讽和鄙视&#xff0c;甚至无视他烦躁的情绪。不过我还是高估了自己的脸皮&#xff0c;最终在其恶狠狠地抛下“…

每日一练:LeeCode-513、找树左下角的值【二叉树】

本文是力扣LeeCode-513、找树左下角的值 学习与理解过程&#xff0c;本文仅做学习之用&#xff0c;对本题感兴趣的小伙伴可以出门左拐LeeCode。 给定一个二叉树的 根节点 root&#xff0c;请找出该二叉树的 最底层 最左边 节点的值。 假设二叉树中至少有一个节点。 示例 1: …

图数据库(neo4j)在工业控制中的应用

最近看到国外发表的一篇文章&#xff0c;提到将OPC UA 模型映射到neo4j图模型数据库中&#xff0c;通过GraphQL 访问效率很高&#xff0c;顿时感觉自己眼睛一亮&#xff0c;这是一个好主意。 图模型 事物的模型中&#xff0c;除了它自身的某些特征之外&#xff0c;还包括它与其…

第十二讲_JavaScript浏览器对象模型BOM

JavaScript浏览器对象模型BOM 1. 浏览器对象模型介绍2. location2.1 常用的属性2.2 常用的方法 3. navigator3.1 常用的属性 4. history4.1 常用的方法&#xff1a; 5. 本地存储 1. 浏览器对象模型介绍 BOM(Browser Object Model) 是指浏览器对象模型&#xff0c;浏览器对象模…

Unity3D实现坦克大战

一、效果图演示 二、逻辑剖析 从界面上&#xff1a; 需要一个Canvas满屏对着用户&#xff0c;该Canvas上展示用户的游戏数据&#xff0c;比如血条。需要一个Canvas放在蓝色坦克上方&#xff0c;也需要实时对着用户&#xff0c;显示敌人的血条信息两个坦克一个平面Plane放草地…

Nice Touch

Nice Touch是Unity最简单的多点触控输入解决方案,来自Corgi Engine和Infinite Runner Engine的制造商。所有功能完整文档论坛 功能列表: • 超级简单的设置 •兼容Unity的新旧输入系统 • 内置多点触控输入 •适用于所有移动设备 • 虚拟操纵杆 • 动态虚拟操纵杆 • 可重新定…

WebChat——一个开源的聊天应用

Web Chat 是开源的聊天系统&#xff0c;支持一键免费部署私人Chat网页的应用程序。 开源地址&#xff1a;https://github.com/loks666/webchat 目录树 TOC &#x1f44b;&#x1f3fb; 开始使用 & 交流&#x1f6f3; 开箱即用 A 使用 Docker 部署B 使用 Docker-compose…

web前端-------弹性盒子(2)

上一讲我们谈的是盒子的容器实行&#xff0c;今天我们来聊一聊弹性盒子的项目属性&#xff1b; *******************&#xff08;1&#xff09;顺序属性 order属性&#xff0c;用于定义容器中项目的出现顺序。 顺序属性值&#xff0c;为整数&#xff0c;可以为负数&#xff…

由亚马逊云科技 Graviton4 驱动的全新内存优化型实例 Amazon EC2 实例(R8g),现已开放预览

下一代 Amazon Elastic Compute CloudAmazon EC2) 实例的预览版现已公开 提供。全新的 R8g 实例 搭载新式 Graviton4 处理器&#xff0c;其性价比远超任何现有的内存优化实例。对于要求较高的内存密集型工作负载&#xff0c;R8g 实例是不二之选&#xff1a;大数据分析、高性能数…

SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式 基础(持续更新~)

具体操作&#xff1a; day2: 作用&#xff1a; 出现跨域问题 配相对应进行配置即可解决&#xff1a; IDEA连接的&#xff0c;在url最后加参数?useSSLfalse注意链接密码是123&#xff08;docker中mysql密码&#xff09; 注意&#xff0c;虚拟机中设置的密码和ip要和主机上…

代码随想录算法训练营第17天 | 110.平衡二叉树, 257. 二叉树的所有路径 ,404.左叶子之和

二叉树理论基础&#xff1a; https://programmercarl.com/%E4%BA%8C%E5%8F%89%E6%A0%91%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html#%E7%AE%97%E6%B3%95%E5%85%AC%E5%BC%80%E8%AF%BE 110.平衡二叉树 题目链接&#xff1a;https://leetcode.cn/problems/balanced-binary-tree…

2024最新最详细【接口测试总结】

序章 ​ 说起接口测试&#xff0c;网上有很多例子&#xff0c;但是当初做为新手的我来说&#xff0c;看了不不知道他们说的什么&#xff0c;觉得接口测试&#xff0c;好高大上。认为学会了接口测试就能屌丝逆袭&#xff0c;走上人生巅峰&#xff0c;迎娶白富美。因此学了点开发…