百科狗-知识改变命运!
--

什么是 Pinia - Pinia(状态管理)

是丫丫呀1年前 (2023-11-21)阅读数 26#技术干货
文章标签都是

什么是 Pinia

Pinia(发音为/piːnjʌ/,如英语中的“peenya”)是最接近有效包名 piña(西班牙语中的 pineapple,即“菠萝”)的词。菠萝花实际上是一组各自独立的花朵,它们结合在一起,由此形成一个多重的水果。与 Store 类似,每一个都是独立诞生的,但最终它们都是相互联系的。

Pinia 最初是为了探索 Vuex 的下一次迭代可能会是什么样子,结合了 Vuex 5 核心团队讨论中的许多想法。最终,我们意识到 Pinia 已经实现了我们在 Vuex 5 中想要的大部分内容,并决定实现它取而代之的是新的建议。与 Vuex 相比,Pinia 提供了一个更简单的 API,具有更少的仪式,提供了Composition-API风格的 API,最重要的是,在与TypeScript一起使用时具有可靠的类型推断支持。

Pinia 适用于 Vue 2 和 Vue 3 ,除非安装方式和 SSR 之外,两者的 API 都是相同的。适用于 Composition API (组合式 API)和 Options API(选项式 API)。

为什么要使用 Pinia?

Pinia 是 Vue 的专属状态管理库,它允许你跨组件或页面共享状态。如果你熟悉 Composition API 的话,你可能会认为可以通过一行简单的export const state = reactive({})来共享一个全局状态。对于单页应用来说确实可以,但如果应用在服务器端渲染,这可能会使你的应用暴露出一些安全漏洞。而如果使用 Pinia,即使在小型单页应用中,你也可以获得如下功能:

  • 开发工具支持
    • 追踪 actions、mutations 的时间线
    • 在组件中展示它们所用到的 Store
    • 让调试更容易的 Time travel
  • 热更新
    • 不必重载页面即可修改 Store
    • 开发时可保持当前的 State
  • 插件:可通过插件扩展 Pinia 功能
  • 为 JS 开发者提供适当的 TypeScript 支持以及自动补全功能
  • 支持服务端渲染


基本示例

Option 式

这就是使用 Pinia 在 API 方面的样子。您首先创建一个 store:

// stores/counter.js
import { defineStore } from 'pinia' export const useCounterStore = defineStore('counter', {
  state: () => {
    return { count: 0 }
  },
  // 也可以这样定义
  // state: () => ({ count: 0 })
  actions: {
    increment() {
      this.count++
    },
  },
})

然后在组件中使用它:

import { useCounterStore } from '@/stores/counter' export default {
  setup() {
    const counter = useCounterStore()

    counter.count++
    // 带有自动补全
    counter.$patch({ count: counter.count + 1 })
    // 或者使用 action 代替
    counter.increment()
  },
}

什么是 Pinia - Pinia(状态管理)


Setup 式

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

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

  return { count, increment }
})


map 助手

如果您仍然不熟悉 Composition API 的setup(),请不要担心,Pinia 还支持一组类似 Vuex 的 map 助手。您以相同的方式定义存储,但随后使用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: {
    // 其他计算属性
    // ...
    // 允许访问 this.counterStore 和 this.userStore ...mapStores(useCounterStore, useUserStore),
    // 允许读取 this.count 和 this.double ...mapState(useCounterStore, ['count', 'double']),
  },
  methods: {
    // 允许读取 this.increment() ...mapActions(useCounterStore, ['increment']),
  },
}


一个实例

这是一个更完整的 API 示例,您将在 Pinia 中使用此样式,即使在 JavaScript 中也是如此。

import { defineStore } from 'pinia' export const useTodos = 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 })
    },
  },
})

鹏仔微信 15129739599 鹏仔QQ344225443 鹏仔前端 pjxi.com 共享博客 sharedbk.com

免责声明:我们致力于保护作者版权,注重分享,当前被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理!邮箱:344225443@qq.com)

图片声明:本站部分配图来自网络。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

内容声明:本文中引用的各种信息及资料(包括但不限于文字、数据、图表及超链接等)均来源于该信息及资料的相关主体(包括但不限于公司、媒体、协会等机构)的官方网站或公开发表的信息。部分内容参考包括:(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供参考使用,不准确地方联系删除处理!本站为非盈利性质站点,本着为中国教育事业出一份力,发布内容不收取任何费用也不接任何广告!)