pinia状态管理工具

Pinia 是 Vue.js 官方推荐的新一代状态管理库,可以看作是 Vuex 的替代品。

1. 什么是 Pinia?

Pinia 是 Vue 的专属状态管理库,它允许你跨组件或页面共享状态。由 Vue.js 核心团队维护,并且对 TypeScript 有着极其出色的支持。

核心设计理念:

  • 直观: 像定义组件一样定义 Store,API 设计尽可能简单直观。
  • 类型安全: 全程提供出色的 TypeScript 支持,无需复杂的包装器。
  • 模块化: 可以拥有多个 Store,并自然地编码,让 Store 自动打包。
  • 轻量: 体积非常小(约 1KB),几乎不会增加打包负担。
  • Composition API: 完美契合 Vue 3 的 Composition API,但同时也支持 Option API。

2. 核心概念(与 Vuex 对比)

Pinia 的核心概念比 Vuex 更加简化,去掉了容易令人混淆的 mutations

概念VuexPinia说明
状态statestate存储应用状态数据的地方
获取状态gettersgetters用于计算和派生状态,相当于 Store 的计算属性
修改状态mutationsactions这是最大的不同。Pinia 中 actions 既可用于同步,也可用于异步操作
异步操作actionsactions在 Pinia 中,异步和同步操作都在 actions 中完成

简单来说,Pinia 就是:state + getters + actions


3. 安装与设置

1. 安装:

npm install pinia
# 或
yarn add pinia

2. 在 Vue 应用中创建并引入 Pinia:

main.jsmain.ts 中:

import { createApp } from 'vue'
import { createPinia } from 'pinia' // 导入 createPinia 函数
import App from './App.vue'// 创建 Pinia 实例
const pinia = createPinia()
// 创建 Vue 应用实例
const app = createApp(App)// 使用 Pinia
app.use(pinia)app.mount('#app')

4. 定义一个 Store

Pinia 使用 defineStore() 函数来定义一个 Store,它需要一个唯一名称(必填)作为第一个参数。这个名称是为了在 Devtools 中调试使用。

Store 有两种定义风格,类似于 Vue 的 Option APIComposition API

方式一:Option Store(选项式风格)

这种方式与 Vuex 的写法非常相似,更容易从 Vuex 迁移过来。

// stores/counter.js
import { defineStore } from 'pinia'export const useCounterStore = defineStore('counter', {// 状态数据state: () => ({count: 0,name: 'Eduardo',}),// 计算属性/派生状态getters: {doubleCount: (state) => state.count * 2,doubleCountPlusOne() { // 可以使用 this 访问整个 store 实例return this.doubleCount + 1},},// 操作方法(同步和异步)actions: {increment() {this.count++ // 通过 this 访问 state},async incrementAsync() {setTimeout(() => {this.increment() // 可以调用其他 action}, 1000)},},
})
方式二:Setup Store(组合式风格)

这种方式使用一个函数来定义 Store,类似于 Vue 的 setup() 函数和 Composition API。

// stores/counter.js
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'export const useCounterStore = defineStore('counter', () => {// state (使用 ref)const count = ref(0)const name = ref('Eduardo')// getters (使用 computed)const doubleCount = computed(() => count.value * 2)const doubleCountPlusOne = computed(() => doubleCount.value + 1)// actions (使用普通函数)function increment() {count.value++}async function incrementAsync() {setTimeout(() => {increment()}, 1000)}// 返回所有需要暴露的状态和方法return {count,name,doubleCount,doubleCountPlusOne,increment,incrementAsync,}
})

如何选择?

  • 如果你习惯 Vuex 或 Option API,选 Option Store
  • 如果你喜欢 Composition API 的灵活性,选 Setup Store

5. 在组件中使用 Store

在组件中,你需要导入并调用你定义的 Store 函数(例如 useCounterStore)来使用它。Pinia 会自动管理单例。

访问 State 和 Getters
<template><div><p>Count: {{ counter.count }}</p><p>Double Count: {{ counter.doubleCount }}</p><p>Double Count Plus One: {{ counter.doubleCountPlusOne }}</p><p>Name: {{ name }}</p> <!-- 直接解构的 name --></div>
</template><script setup>
import { useCounterStore } from '@/stores/counter'
import { storeToRefs } from 'pinia' // 重要!用于保持响应式// 在 setup 中调用 Store 函数
const counter = useCounterStore()// ❌ 错误:直接解构会失去响应式!
// const { count, name } = counter// ✅ 正确:使用 storeToRefs 解构可以保持响应式
const { count, name } = storeToRefs(counter)
// 注意:actions 不需要也不应该用 storeToRefs 解构,直接通过 counter 调用即可
</script>
调用 Actions
<template><div><button @click="counter.increment()">Increment</button><button @click="counter.incrementAsync()">Increment Async</button></div>
</template><script setup>
import { useCounterStore } from '@/stores/counter'const counter = useCounterStore()// 也可以在方法或事件处理逻辑中调用
function handleClick() {counter.increment()
}
</script>

6. 状态修改与响应式

  • 直接修改: 你可以直接修改状态(counter.count++),这在 Pinia 中是允许的。
  • 批量修改: 使用 $patch 方法进行批量更新,这有利于性能优化,并且 Devtools 会将其记录为一次修改。
const counter = useCounterStore()// 方式一:传入一个部分 state 对象
counter.$patch({count: counter.count + 1,name: 'New Name',
})// 方式二:传入一个修改函数,适用于修改数组或嵌套对象
counter.$patch((state) => {state.items.push({ name: 'shoes', quantity: 1 })state.hasChanged = true
})
  • 替换整个状态: 可以通过 $state 属性替换整个 store 的状态。
counter.$state = { count: 1000, name: 'Paimon' }

7. 高级特性与技巧

订阅状态变化

可以使用 $subscribe 来监听 state 及其变化,类似于 Vuex 的 subscribe。常用于持久化等操作。

counter.$subscribe((mutation, state) => {// mutation 包含了修改的信息(events, type, storeId)// state 是修改后的新状态localStorage.setItem('counter', JSON.stringify(state))
})
订阅 Action

可以使用 $onAction 来监听 action 及其结果。

const unsubscribe = counter.$onAction(({ name, store, args, after, onError }) => {// action 调用前执行console.log(`Start "${name}" with params [${args.join(', ')}].`)// after 在 action 成功并返回后执行after((result) => {console.log(`Finished "${name}". Result was: ${result}.`)})// onError 在 action 抛出错误或 reject 时执行onError((error) => {console.warn(`Failed "${name}": ${error}.`)})
})// 手动移除订阅
// unsubscribe()
模块化(多 Store)

Pinia 天生是模块化的。你只需要定义多个不同的 Store 并在不同组件中引入它们即可。

// stores/user.js
export const useUserStore = defineStore('user', {state: () => ({ user: null }),// ...
})// stores/cart.js
export const useCartStore = defineStore('cart', {state: () => ({ items: [] }),// ...
})

然后在组件中可以同时使用多个 Store:

<script setup>
import { useUserStore } from '@/stores/user'
import { useCartStore } from '@/stores/cart'const userStore = useUserStore()
const cartStore = useCartStore()
// 甚至可以在一个 Store 中使用另一个 Store
// (注意避免循环引用)
</script>

总结:为什么选择 Pinia?

  1. 更简单的 API: 去除 mutations,只有 state, getters, actions,概念更清晰。
  2. 完美的 TS 支持: 无需复杂配置,类型推断非常强大。
  3. 模块化设计: 不需要嵌套模块,多个 Store 自然拆分。
  4. 轻量级: 体积极小,对应用打包体积影响几乎可以忽略不计。
  5. Composition API: 与 Vue 3 的编程思想完美契合,使用起来更加灵活。
  6. 官方推荐: 作为 Vuex 的继任者,是未来 Vue 生态的状态管理首选。

对于新项目,强烈推荐直接使用 Pinia。对于老项目,如果 Vuex 能满足需求且没有维护性问题,不一定需要立即迁移,但 Pinia 绝对是未来趋势。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/921167.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/921167.shtml
英文地址,请注明出处:http://en.pswp.cn/news/921167.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【初始web3】什么是web3

前言你是否还记得&#xff0c;曾经在社交媒体上发布精彩内容&#xff0c;平台却随意封禁你的账号&#xff1f;你是否曾疑惑&#xff0c;为什么你创造的数据价值亿万&#xff0c;而你自己却一无所获&#xff1f;这&#xff0c;就是Web2时代的痛。而Web3的到来&#xff0c;正试图…

构建下一代互联网:解码Web3、区块链、协议与云计算的协同演进

我们正站在互联网历史性变革的门口。从只能读取信息的Web1&#xff0c;到可以读写、高度中心化的Web2&#xff0c;我们即将迈入一个价值可以直接传递的Web3时代。这个新时代并非由单一技术驱动&#xff0c;而是由区块链、去中心化协议和云计算等一系列技术的融合与协同所构建。…

小迪安全v2023学习笔记(七十六讲)—— Fuzz模糊测试口令爆破目录爆破参数爆破Payload爆破

文章目录前记WEB攻防——第七十六天Fuzz模糊测试篇&JS算法口令&隐藏参数&盲Payload&未知文件目录Fuzz知识含义Fuzz的核心思想Fuzz应用场景Fuzz应用Fuzz字典项目Fuzz技术 - 用户口令-常规&模块&JS插件常规模块JS插件JsEncrypterBurpCryptoFuzz技术 - 目…

在windows server 2022搭建gitlab……但是失败了

在windows server 2022搭建gitlab……但是失败了1. 前言2. 安装ubuntu环境2. 安装docker3. 映射3.1 端口映射3.2 路径映射1. 前言 上一篇&#xff1a;在windows本地机搭建gitlab 本来按理来说没必要另起一篇&#xff0c;但是没想到&#xff0c;在新机器的windows server 2022…

蓝桥杯算法之基础知识(4)

目录 Ⅰ.sorted排序 Ⅱ.排序具体的方法 &#xff08;1&#xff09;sort的神方法&#xff08;注意是sort&#xff09; &#xff08;2&#xff09;sorted的神方法&#xff08;注意这里是sorted&#xff09; 常见场景 1. 单关键字排序 2. 多关键字排序 3.按倒序字符串排序&#xf…

GOFLY开源客服系统-处理gin框架下的session中间件

了解更多&#xff0c;搜索:"程序员老狼" 在当今数字化时代&#xff0c;在线客服系统已成为企业与客户沟通的重要桥梁。作为GOFLY客服系统的开发者&#xff0c;我今天要分享我们如何在系统中实现安全可靠的会话管理机制——这是保障用户数据安全的核心技术。 为什么…

Burp Suite 插件 | 提供强大的框架自动化安全扫描功能。目前支持1000+POC、支持动态加载POC、指定框架扫描。

工具介绍 Rinte 是一款专为渗透测试人员设计的 Burp Suite 插件&#xff0c;提供强大的自动化安全扫描功能。该插件集成了框架检测、漏洞扫描和敏感路径扫描等多种功能&#xff0c;帮助安全研究人员快速识别目标系统的安全漏洞。支持1000框架POC、支持动态加载POC、指定框架扫描…

记录测试环境hertzbeat压测cpu高,oom问题排查。jvm,mat,visulavm

记录测试环境hertzbeat压测cpu高&#xff0c;oom问题排查。jvm&#xff0c;mat&#xff0c;visulavm 一&#xff0c;问题背景 运维平台&#xff0c;采用hertzbeat开源代码进行采集。对单个设备连接&#xff0c;采集9个指标。目前hertzbeat对1个设备连接&#xff0c;下发9次单独…

基于 CC-Link IE FB 转 DeviceNet 技术的三菱 PLC 与发那科机器人在汽车涂装线的精准喷涂联动

案例背景在汽车制造行业&#xff0c;生产线的高效协同是提高生产效率和产品质量的关键。某汽车制造企业的车身焊接车间采用了基于 CC-Link IE FB 主站的三菱 Q 系列 PLC&#xff0c;凭借其强大的功能和稳定的性能&#xff0c;对焊接机器人等设备进行精准控制。而在涂装车间&…

极空间打造 “超级中枢”,从书签笔记到聊天分享,一键全搞定!

「NAS、键盘、路由器年轻就要多折腾&#xff0c;我是爱折腾的熊猫&#xff0c;今天又给大家分享最近折腾的内容了&#xff0c;关注是对我最大的支持&#xff0c;阿里嘎多」引言书签项目熊猫介绍过不少啦&#xff0c;但今天要介绍的这个项目&#xff0c;大不一样。平常的书签&am…

Swift 解法详解:LeetCode 368《最大整除子集》

文章目录摘要描述题解答案题解代码分析代码拆解示例测试及结果时间复杂度空间复杂度总结摘要 有时候我们会遇到这样的问题&#xff1a;给定一堆数&#xff0c;如何从中挑出一个子集&#xff0c;让这个子集里的每一对数都能互相整除&#xff1f;题目要求我们找出最大的这样一个…

python数据分析 与spark、hive数据分析对比

Python 数据分析与 Spark、Hive 数据分析在应用场景、数据处理能力、编程模型等方面存在差异&#xff0c;以下是详细对比&#xff1a;​数据处理规模​Python 数据分析&#xff1a;​特点&#xff1a;Python 数据分析常用库如Pandas&#xff0c;在单机环境下对中小规模数据集&a…

专题:2025全球新能源汽车供应链核心领域研究报告|附300+份报告PDF、数据仪表盘汇总下载

原文链接&#xff1a;https://tecdat.cn/?p43781 原文出处&#xff1a;拓端抖音号拓端tecdat 2024年&#xff0c;全球汽车产业站在了“旧秩序打破、新格局建立”的十字路口——一边是传统供应链受宏观经济波动、地缘博弈冲击&#xff0c;全球零部件企业营收首次出现负增长&…

从数据孤岛到智能中枢:RAG与智能体协同架构如何重塑企业知识库

1. 前言企业知识管理正面临前所未有的挑战。分散在各个系统中的文档、报告、邮件和数据库形成了数据孤岛&#xff0c;而大语言模型在缺乏准确知识支撑时容易产生幻觉回答。这种矛盾催生了检索增强生成&#xff08;RAG&#xff09;技术的快速发展。RAG不仅仅是技术组合&#xff…

UBUNTU之Onvif开源服务器onvif_srvd:2、测试

运行 # eth0: 网卡 # 192.168.0.229: IPsudo ./onvif_srvd \--ifs eth0 \--scope onvif://www.onvif.org/name/TestDev \--scope onvif://www.onvif.org/Profile/S \--name RTSP \--width 800 --height 600 \--url rtsp://192.168.0.229:554/unicast \--type JPEG 测试 使用…

项目中常用的git命令

Git介绍Git是一个分布式版本控制系统&#xff0c;主要作用就是记录代码的历史变化&#xff0c;让开发者可以查看任意时间点的代码&#xff0c;回滚到某个历史版本&#xff0c;对比不同版本之间的差异。在企业开发中&#xff0c;通过是通过多人协作开发&#xff0c;具体分支可以…

C 语言标准输入输出库:`stdio.h` 的使用详解

1. 概述 在 C 语言中&#xff0c;stdio.h&#xff08;Standard Input Output Header&#xff09;是一个标准库头文件&#xff0c;主要用于提供输入与输出功能。几乎所有的 C 程序都会用到它&#xff0c;因为它定义了用于读取、写入、格式化、文件操作等常用函数。 要在程序中使…

flume扩展实战:自定义拦截器、Source 与 Sink 全指南

flume扩展实战&#xff1a;自定义拦截器、Source 与 Sink 全指南 Flume 内置的组件虽然能满足大部分场景&#xff0c;但在复杂业务需求下&#xff08;如特殊格式数据采集、定制化数据清洗&#xff09;&#xff0c;需要通过自定义组件扩展其功能。本文将详细讲解如何自定义 Flu…

【数学建模】数学建模应掌握的十类算法

【数学建模】数学建模应掌握的十类算法前言数学建模竞赛官网1. 全国大学生数学建模竞赛官网2. 美国大学生数学建模竞赛官网3. Matlab 网站4. 研究生数学建模竞赛官网数学建模应掌握的十类算法1. 蒙特卡罗方法(Monte-Carlo方法, MC)2. 数据拟合、参数估计、插值等数据处理算法3.…

物联网开发学习总结(1)—— IOT 设备 OTA 升级方案

在物联网设备数量呈指数级增长的今天&#xff0c;如何高效、可靠地实现设备固件升级&#xff08;OTA&#xff09;成为了每个物联网开发者必须面对的重要课题。传统的HTTP升级方案虽然简单易用&#xff0c;但随着设备规模的扩大&#xff0c;其局限性日益明显。 一、HTTP OTA升级…