新一代vue状态管理工具Pinia

轻量状态管理工具 Pinia

前言

作为前端开发,你肯定知道状态管理是日常开发很重要的一部分。你肯定也听过许多状态管理工具,今天我们说一下 Vue 系列的新起之秀 Pinia。

什么是 Pinia

Pinia 和 Vuex 一样是专门为 Vue 设计的状态管理库,它允许你跨组件或页面共享状态,Api 设计比 Vuex 更简单易学,且同时支持 Vue2.0 和 Vue3.0。

安装

csharp 复制代码
yarn add pinia
// 或者使用 npm
npm install pinia

创建一个 Pinia 实例 (根 Store ) 并将其传递给应用:

javascript 复制代码
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
​
const pinia = createPinia()
const app = createApp(App)
​
app.use(pinia)
app.mount('#app')

如何创建 Store

在创建 Store 之前我们先简单描述一下什么是 Store

Store (如 Pinia) 是一个保存状态和业务逻辑的实体,它承载着全局状态,每个组件都可以读取和写入它。它有三个概念:State、Getter 和 Action,可以想象成组件中的 DataComputedMethods

创建一个 Store,在 src/stores 创建一个 counter.ts

javascript 复制代码
// stores/counter.ts
​
// options 模式
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', {
  state: () => {
    return { count: 0 }
  },
  actions: {
    increment() {
      this.count++
    },
  },
})
​
​
// Setup 模式
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', () => {
  const count = ref(0)  
  function increment() {
    count.value++
  }
​
  return { count, increment }
})
​

上述代码就是创建一个 Store,DefineStore 可以随意命名,但最好保持 Use 这种风格,DefineStore 第一个参数是唯一的,不可重复,因为是应用中 Store 的唯一 ID,Pinia 将用 ID 连接 Store 和 Devtools。DefineStore 的第二个参数可以接受 Setup 函数或 Option 对象。

State

State 的使用

arduino 复制代码
import { useCounterStore } from '@/stores/counter'
const counter = useCounterStore()
​
</script>
​
<template>
  <div class="greetings">
   {{counter.count}}
  </div>
</template>

修改 State

perl 复制代码
// 直接修改
counter.count++
// 或者使用 $patch 修改 (可以修改多个属性)
counter.$patch({
  count: counter.count + 1,
})
​

重置 State

perl 复制代码
// 通过调用 store 的 $reset() 方法将 state 重置为初始值。
counter.$reset()

解构:

arduino 复制代码
import { useCounterStore } from '@/stores/counter'
const counter = useCounterStore()
const {count} = counter
</script>
​
<template>
  <div class="greetings">
   {{counter.count}}
   {{count}}
  </div>
</template>
​

State 也可以使用解构,但是解构会失去响应式,需要 StoreToRefs 避免丢失响应式

javascript 复制代码
import { storeToRefs } from 'pinia'
const counter = useCounterStore()
const {count} = storeToRefs(counter)

Getter

Getter 完全等同于 Store 的 State 的计算属性。写法也类似,可以使用 this 访问整个 Store 的实例,甚至可以访问其他 Store 的 Getter,而且可以和 Vue 一样返回一个函数 接受参数(但是这样 Getter 将不再被缓存,只是个被调用的函数),使用同 State 访问模式一样。

typescript 复制代码
import { useOtherStore } from './other-store'

export const useCounterStore = defineStore('counter', {
  state: () => {
    return { count: 0 }
  },
  getters: {
    // 使用 state 可以自动推到出类型
    doubleCount(state) {
      return state.count * 2
    },
    // 返回类型必须明确设置
    doublePlusOne(): number {
      return this.doubleCount + 1
    },
   //还可以访问其他 getter
   otherGetter(state) {
      const otherStore = useOtherStore()
      return state.count + otherStore.count
    },
  },
  actions: {
    increment() {
      this.count++
    },
  },
})

Action

Action 相当于组件中的 Methods,类似 Getter,Action 也可通过 this 访问整个 Store 的实例 Action 也可以是异步的,还可以访问其他Store 的 Action。

javascript 复制代码
import { useAuthStore } from './user'

export const useCounterStore = defineStore('counter', {
  state: () => {
    return { 
      userInfo: {}
    }
  },
  actions: {
   async fetchUserInfo() {
      const auth = useAuthStore()
      if (auth.isAuthenticated) {
        this.userInfo = await fetchUserInfo()
      }
    },
  },
})

调用

xml 复制代码
<script setup>
const store = useCounterStore()
// 将 action 作为 store 的方法进行调用
store.fetchUserInfo()
</script>
<template>
  <!-- 即使在模板中也可以 -->
  <button @click="store.fetchUserInfo()">点击我</button>
</template>

总结

以上就是 Pinia 的基本使用。回顾以前使用的 Vuex 是不是 Api 是不是非常简洁,Pinia 抛弃了 Mutation 和 Module,只保留State、Getter 和 Action,而且使用方法和组件中 DataComputedMethods 类似,上手零成本。而且支持 ts,极致轻量化代码只有1kb左右。

参考链接

pinia.web3doc.top/

推荐阅读

Cola-StateMachine状态机的实战使用

Redisson杂谈

react-grid-layout 之核心代码分析与实践

@Transactional注解使用以及事务失效的场景

REDIS 数据结构与对象

开源作品

  • 政采云前端小报

开源地址 www.zoo.team/openweekly/ (小报官网首页有微信交流群)

  • 商品选择 sku 插件

开源地址 github.com/zcy-inc/sku...

招贤纳士

政采云技术团队(Zero),Base 杭州,一个富有激情和技术匠心精神的成长型团队。规模 500 人左右,在日常业务开发之外,还分别在云原生、区块链、人工智能、低代码平台、中间件、大数据、物料体系、工程平台、性能体验、可视化等领域进行技术探索和实践,推动并落地了一系列的内部技术产品,持续探索技术的新边界。此外,团队还纷纷投身社区建设,目前已经是 google flutter、scikit-learn、Apache Dubbo、Apache Rocketmq、Apache Pulsar、CNCF Dapr、Apache DolphinScheduler、alibaba Seata 等众多优秀开源社区的贡献者。

如果你想改变一直被事折腾,希望开始折腾事;如果你想改变一直被告诫需要多些想法,却无从破局;如果你想改变你有能力去做成那个结果,却不需要你;如果你想改变你想做成的事需要一个团队去支撑,但没你带人的位置;如果你想改变本来悟性不错,但总是有那一层窗户纸的模糊......如果你相信相信的力量,相信平凡人能成就非凡事,相信能遇到更好的自己。如果你希望参与到随着业务腾飞的过程,亲手推动一个有着深入的业务理解、完善的技术体系、技术创造价值、影响力外溢的技术团队的成长过程,我觉得我们该聊聊。任何时间,等着你写点什么,发给 zcy-tc@cai-inc.com

相关推荐
SEO_juper2 分钟前
2026年用Python分析网站访问日志:看清Googlebot和AI爬虫怎么爬你的站(附完整代码)
开发语言·前端·seo·独立站·谷歌优化
摸鱼仙人~3 分钟前
React 原理进阶:彻底理解 re-render、React.memo、useMemo 与 useCallback
前端·vue.js
IMPYLH7 分钟前
HTML 的 <small> 元素
前端·网络·html
IT_陈寒8 分钟前
Vue的响应式让我加班到凌晨,问题竟出在这个不起眼的地方
前端·人工智能·后端
AlienZHOU9 小时前
AI Coding 时代下,我的技术面试实践分享
前端·后端·面试
Captaincc12 小时前
AI用量v0.1.11更新发布 新增 jusage doctor 诊断指令 托盘展示token 和余额 新增 AutoClaw 支持
前端·后端·vibecoding
计算机魔术师13 小时前
德国Wiki被黑后两周,OpenAI终于把模型失控的账本摊开了
前端
kyriewen14 小时前
我让 AI 当面试官面了我一轮:第 3 个追问我就卡住了(附 10 道追问清单)
前端·面试·ai编程
IT_陈寒14 小时前
Python的GIL把我坑惨了,多线程跑得比单线程还慢
前端·人工智能·后端
前端snow15 小时前
ai agent --- 多agent框架之图编排引擎-langgraph
前端