千家信息网

Vue中如何使用pinia

发表于:2025-01-19 作者:千家信息网编辑
千家信息网最后更新 2025年01月19日,这篇文章主要介绍了Vue中如何使用pinia的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Vue中如何使用pinia文章都会有所收获,下面我们一起来看看吧。什么是Pini
千家信息网最后更新 2025年01月19日Vue中如何使用pinia

这篇文章主要介绍了Vue中如何使用pinia的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Vue中如何使用pinia文章都会有所收获,下面我们一起来看看吧。

什么是Pinia?

Pinia最初是在 2019 年 11 月左右重新设计使用 Composition API的 Vue Store 外观的实验。从那时起,最初的原则仍然相同,但 Pinia 适用于 Vue 2 和 Vue 3 ,并且不需要你使用组合 API。除了安装SSR之外,两者的 API 都是相同的,并且这些文档针对 Vue 3 ,并在必要时提供有关 Vue 2 的注释,以便 Vue 2 和 Vue 3 用户可以阅读!

为什么要使用 Pinia?

Pinia 是 Vue 的存储库,它允许您跨组件/页面共享状态。ç 这对于单页应用程序来说是正确的,但如果它是服务器端呈现的,则会将您的应用程序暴露给安全漏洞。 但即使在小型单页应用程序中,您也可以从使用 Pinia 中获得很多好处:

  • 开发工具支持

    • 跟踪动作、突变的时间表

    • 商店出现在使用它们的组件中

    • 时间旅行和更容易的调试

  • 热模块更换

    • 在不重新加载页面的情况下修改您的商店

    • 在开发时保持任何现有状态

  • 插件:使用插件扩展 Pinia 功能

  • 为 JS 用户提供适当的 TypeScript 支持或自动完成功能

  • 服务器端渲染支持

基本示例

这就是使用 pinia 在 API 方面的样子(请务必查看入门以获取完整说明)。您首先创建一个商店:

// stores/counter.jsimport { defineStore } from 'pinia'export const useCounterStore = defineStore('counter', {  state: () => {    return { count: 0 }  },  // could also be defined as  // state: () => ({ count: 0 })  actions: {    increment() {      this.count++    },  },})

然后在组件中使用它:

import { useCounterStore } from '@/stores/counter'export default {  setup() {    const counter = useCounterStore()    counter.count++    // with autocompletion ✨    counter.$patch({ count: counter.count + 1 })    // or using an action instead    counter.increment()  },}

你甚至可以使用一个函数(类似于一个组件setup())来为更高级的用例定义一个 Store:

export const useCounterStore = defineStore('counter', () => {  const count = ref(0)  function increment() {    count.value++  }  return { count, increment }})

如果您仍然不熟悉setup()Composition API,请不要担心,Pinia 还支持一组类似的地图助手,例如 Vuex。您以相同的方式定义存储,但随后使用mapStores()mapState()mapActions()

const useCounterStore = defineStore('counter', {  state: () => ({ count: 0 }),  getters: {    double: (state) => state.count * 2,  },  actions: {    increment() {      this.count++    }  }})const useUserStore = defineStore('user', {  // ...})export default {  computed: {    // other computed properties    // ...    // gives access to this.counterStore and this.userStore    ...mapStores(useCounterStore, useUserStore)    // gives read access to this.count and this.double    ...mapState(useCounterStore, ['count', 'double']),  },  methods: {    // gives access to this.increment()    ...mapActions(useCounterStore, ['increment']),  },}

您将在核心概念中找到有关每个地图助手的更多信息。

为什么选择Pinia

Pinia(发音为/piːnjʌ/,如英语中的"peenya")是最接近piña(西班牙语中的菠萝)的词,它是一个有效的包名称。菠萝实际上是一组单独的花朵,它们结合在一起形成多个水果。与商店类似,每一家都是独立诞生的,但最终都是相互联系的。它也是一种美味的热带水果,原产于南美洲。

一个更现实的例子

这是一个更完整的 API 示例,您将在 Pinia中使用类型,即使在 JavaScript 中也是如此。对于某些人来说,这可能足以在不进一步阅读的情况下开始使用,但我们仍然建议您查看文档的其余部分,甚至跳过此示例并在阅读完所有核心概念后返回。

import { defineStore } from 'pinia'export const todos = defineStore('todos', {  state: () => ({    /** @type {{ text: string, id: number, isFinished: boolean }[]} */    todos: [],    /** @type {'all' | 'finished' | 'unfinished'} */    filter: 'all',    // type will be automatically inferred to number    nextId: 0,  }),  getters: {    finishedTodos(state) {      // autocompletion! ✨      return state.todos.filter((todo) => todo.isFinished)    },    unfinishedTodos(state) {      return state.todos.filter((todo) => !todo.isFinished)    },    /**     * @returns {{ text: string, id: number, isFinished: boolean }[]}     */    filteredTodos(state) {      if (this.filter === 'finished') {        // call other getters with autocompletion ✨        return this.finishedTodos      } else if (this.filter === 'unfinished') {        return this.unfinishedTodos      }      return this.todos    },  },  actions: {    // any amount of arguments, return a promise or not    addTodo(text) {      // you can directly mutate the state      this.todos.push({ text, id: this.nextId++, isFinished: false })    },  },})

与 Vuex 的比较

Pinia 试图尽可能地接近 Vuex 的理念。它旨在测试 Vuex 下一次迭代的提案,并且取得了成功,因为我们目前有一个针对 Vuex 5 的开放 RFC,其 API 与 Pinia 使用的 API 非常相似。请注意,我 (Eduardo),Pinia 的作者,是 Vue.js 核心团队的一员,并积极参与了 Router 和 Vuex 等 API 的设计。我个人对这个项目的意图是重新设计使用全球商店的体验,同时保持 Vue 的平易近人的理念。我保持 Pinia 的 API 与 Vuex 一样接近,因为它不断向前发展,以使人们更容易迁移到 Vuex,甚至在未来融合两个项目(在 Vuex 下)。

RFC

虽然 Vuex 通过 RFC 从社区收集尽可能多的反馈,但 Pinia 没有。我根据我开发应用程序、阅读其他人的代码、为使用 Pinia 的客户工作以及在 Discord 上回答问题的经验来测试想法。这使我能够提供一种适用于各种情况和应用程序大小的有效解决方案。我经常发布并在保持其核心 API 不变的同时使库不断发展。

与 Vuex 3.x/4.x 的比较

Vuex 3.x 是 Vuex 的 Vue 2 而 Vuex 4.x 是 Vue 3

Pinia API 与 Vuex ≤4 有很大不同,即:

  • 突变不再存在。他们经常被认为是非常冗长的。他们最初带来了 devtools 集成,但这不再是问题。

  • 无需创建自定义复杂包装器来支持 TypeScript,所有内容都是类型化的,并且 API 的设计方式尽可能利用 TS 类型推断。

  • 不再需要注入魔法字符串、导入函数、调用它们,享受自动完成功能!

  • 无需动态添加商店,默认情况下它们都是动态的,您甚至都不会注意到。请注意,您仍然可以随时手动使用商店进行注册,但因为它是自动的,您无需担心。

  • 不再有模块的嵌套结构。您仍然可以通过在另一个商店中导入和使用商店来隐式嵌套商店,但 Pinia 通过设计提供平面结构,同时仍然支持商店之间的交叉组合方式。你甚至可以有 store 的循环依赖

  • 没有命名空间的模块。鉴于商店的扁平架构,"命名空间"商店是其定义方式所固有的,您可以说所有商店都是命名空间的。

关于"Vue中如何使用pinia"这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对"Vue中如何使用pinia"知识都有一定的了解,大家如果还想学习更多知识,欢迎关注行业资讯频道。

0