大厂技术 高级前端 Node进阶
点击上方 程序员成长指北,关注公众号
回复1,加入高级Node交流群
前言
说起Pinia,熟悉vue3开发的程序员肯定不会陌生,甚至被vue官方推荐取代vuex,成为vue全家桶之一。
疑惑
还记得之前用 vuex 时,更改state还分同步和异步(这里有尤雨溪的回答)
这个功能,面试还被问过为什么…,当时也是不太理解,觉得肯定有他的道理,谁知看了pinia后,更改state同步异步都可以……
回到正题:但我们真的需要Pinia/Vuex吗?Pinia/Vuex解决了什么问题?没有Pinia/Vuex前我们是怎么做的呢,会有什么问题?
刨根
对于以上问题,以下是本人的一些思考(有不足之处,还望赐教)
为什么需要Pinia,它解决了什么问题?先查下官网/别人怎么说;
网上很多是说,Pinia 是 Vue.js 的轻量级状态管理库;
官方文档如下描述:
对于以上支撑观点,下面一个个来看,看下Pinia是否是必须的:
1. Pinia 是 Vue.js 的轻量级状态管理库
详阅vue官网关于状态管理 的文章,里面提到一个场景:多个组件共享一个共同的状态时,用vue原生的能力实现有点麻烦,文章推荐以下方法,将公用的数据提取到全局,这样需要的组件可以直接引用:
// store.js
import { reactive } from "vue";
export const store = reactive({
count: 0,
// ...
});
import { store } from './store.js'
From A: {{ store.count }}
import { store } from './store.js'
From B: {{ store.count }}
那我们先用这个简单的方法解决状态管理的问题,后面看下会遇到什么问题;
2. Devtools 支持(…)
不好意思,本人开发过好几个vue项目,从来没用过 vue devtools,都是console.log一把梭,目前感觉可以满足调试需要,这个在我这里就先跳过了,忽略!(用vue devtools很爽的可以评论分享下使用场景&经验)
3. 热更新(不必重载页面即可修改 Store、开发时可保持当前的 State)
呃…,没看太懂这个场景,如果说是热更新,上面的简单方法也可以做到,而且严格上说这应该是构建工具提供的能力吧,像webpack hmr/vite hmr;
既然简单的方法也可以做到我理解的热更新,平时好像也没有这方面的困扰,先跳过,忽略!(有这方面需要的请分享下经验,跪求)
4. 插件:可通过插件扩展 Pinia 功能
这个等需要用Pinia再考虑这个,先跳过,忽略!
5. 为 JS 开发者提供适当的 TypeScript 支持以及自动补全功能
呃呃,上面的简单方法也可以做到,而且ts声明更方便,如下:
// store.ts
import { reactive } from "vue";
interface IStore {
count: number;
// ...
}
export const store = reactive({
count: 0,
// ...
});
有了ts声明后,自动补全 是编辑器提供的功能。先跳过,忽略!
6. 支持服务端渲染简单方案
先说上面简单的方法,用该方法会导致跨请求状态污染 问题;如下图,从技术上讲,我们可以在每个请求上重新初始化 store
对于上图的 初始化 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方案
link:
经过对比,简单方法个人认为也可以支持服务端渲染,且没有额外的概念、学习成本!
结论
据以上分析,我发现并没有必须用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 }
}
其他简单方法不好维护
有人拿出官方文档说上面简单的方法从长远来看不好维护。
长远来看应该是数据量变多会导致不好维护吧,但随着数据量增多,我们把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 直接提供了持久化的插件。但我总感觉没触到事情本质,于是搜一下具体的场景:
那针对以上场景,简单来做不是哪个需要缓存就缓存哪个吗,比如登录信息需要缓存:
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);
}
// ...
所以,我理解这种持久化问题和状态管理不应该放在一起讨论,我建议是根据场景,按需缓存
最后
纸上得来终觉浅,绝知此事要躬行
很多时候感觉在前端学不动了,其中原因之一必有:概念太多、轮子太多、技术更新太快,需要不断学习……
但个人感觉很多概念都是莫须有的,利用原生知识亦可解决,而无需增加心智负担,但要识别这些信息谈何容易啊,希望我们始终保留对问题本质的好奇吧。
Node 社群
我组建了一个氛围特别好的 Node.js 社群,里面有很多 Node.js小伙伴,如果你对Node.js学习感兴趣的话(后续有计划也可以),我们可以一起进行Node.js相关的交流、学习、共建。下方加 考拉 好友回复「Node」即可。
“分享、点赞、在看” 支持一下
限 时 特 惠: 本站每日持续更新海量各大内部创业教程,一年会员只需98元,全站资源免费下载 点击查看详情
站 长 微 信: lzxmw777声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。