告别 Vuex,拥抱 Pinia
还记得我们曾经为 Vuex 苦恼的日子吗?无尽的 mutations、奇怪的 commit 和 dispatch 语法,以及让人头疼的 TypeScript 类型。Vue 团队似乎听到了我们的祈祷,发布了 Pinia。这不仅仅是一个状态管理库,而是 Vuex 的官方继任者,它让前端开发者的生活变得更加轻松。
顺便说一下,这个名字是一个有趣的双关语。Pinia 听起来像西班牙语单词«piña»(菠萝)。创造者将 store 比作菠萝:它是由一组独立的花朵共同形成一个单一的水果。应用程序中的每个 store 都是独立创建的,但最终它们作为一个团队协同工作。
它是什么以及为什么你需要它
简而言之,Pinia 是一个轻量级的 Vue store,完全支持 Composition API。它只有约 1 KB,支持热模块替换,并且与 DevTools 配合良好。
与旧方法的主要区别在于没有 mutations。现在你可以在 actions 中直接改变状态,这大大减少了样板代码。如果你正在使用 Vue 3,Pinia 实际上是标准选择。对于仍在使用 Vue 2 的人,也有向后兼容性,所以迁移不会是一场灾难。
为什么开发者选择这个 Store
我发现了几个真正改变工作流程的要点。
开箱即用的 TypeScript 支持
在 Vuex 中,类型定义常常像是用拐杖走路。在 Pinia 中,一切都不同了。它是用 TypeScript 编写的,所以自动补全功能完美运行。你不需要为每个 getter 或 action 手动描述接口——库会自动推断你返回的内容。
模块化,无需额外复杂性
忘掉嵌套模块和复杂的路径吧。在 Pinia 中,你只需在不同文件中创建不同的 store,然后在需要的地方导入它们。这使得架构更清晰:每个组件只获取它实际需要的数据。
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', {
state: () => ({
count: 0,
}),
getters: {
doubleCount: (state) => state.count * 2,
},
actions: {
increment() {
this.count++
},
},
})
简单的集成
只需几行代码就能连接这个库。它与 Nuxt 配合得很好,支持服务端渲染(SSR),这一点很棒。
import { createPinia } from 'pinia'
const pinia = createPinia()
app.use(pinia)
在实践中它是如何工作的
想象一下你在一个在线商店中有一个购物车。以前,你必须注册一个模块,追踪路径命名,并编写调用 mutations 的 actions。使用 Pinia,你可以像调用普通函数一样在组件中直接调用 store 方法。
为了在保持响应式的同时获取数据,有一个方便的 storeToRefs helper。当你需要解构一个 store 但又不想破坏它与状态的连接时,这就派上用场了。
import { useCartStore } from '@/stores/cart'
import { storeToRefs } from 'pinia'
const cart = useCartStore()
const { items, total } = storeToRefs(cart)
值得切换吗
如果你正在启动一个新的 Vue 3 项目,Pinia 几乎是唯一的选择。它更简单、更快、更现代。如果你有一个旧的 Vuex 项目,没有必要急于迁移,但对于新功能我建议尝试这种方法。
该项目由 Vue 核心团队成员 Eduardo San Martin Morote(posva)积极维护。这给了我们信心,这个库不会在一个月内消失。此外,Pinia 拥有出色的文档和活跃的社区。
你可以在 StackBlitz 上试用这个项目:
它绝对适合这些人:
- 受够了 Vuex 冗长的人。
- 重视高质量自动补全的 TypeScript 爱好者。
- Nuxt 3 开发者,Pinia 是他们推荐的解决方案。
也许唯一的缺点——如果你习惯了 Vuex 严格的结构和必需的 mutations,Pinia 的自由可能会在一开始显得奇怪。但好的东西总是很快就能习惯的。
相关项目