新一代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

相关推荐
崔庆才丨静觅7 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60618 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了8 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅8 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅9 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅9 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment9 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅9 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊9 小时前
jwt介绍
前端
爱敲代码的小鱼9 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax