Vue状态管理:Pinia 与 Vuex 的使用方法与对比【文章附有完整案例】

最近在接手vue项目的需求,因为之前一直在做react的需求,日常的vue练习也少了很多,导致现在接手vue项目,很多关于vue的知识点基本上忘得干干净净了。但是好在有基础,重新学也会很快掌握。分享这个过程中的一些复习内容。

本篇分享【状态管理】相关的内容。


一、状态管理概述

状态管理用于解决 Vue 应用中组件间的数据共享问题,尤其适合以下场景:

  • 多个组件需要共享同一数据
  • 不同组件需要修改同一份数据
  • 跨层级组件间的通信

Vuex 作为 Vue 官方推荐的状态管理库已有多年历史,而 Pinia 则是 Vuex 团队在 Vue 3 时代推出的新方案,目前已成为 Vue 3 项目的官方推荐。

二、Vuex 4.x 的使用方法

Vuex 4 专为 Vue 3 设计,保留了 Vuex 的核心概念,但做了适配 Composition API 的改进。

1. 安装与配置

npm install vuex@4

创建 store/index.js:

import { createStore } from 'vuex'export default createStore({state() {return {count: 0,message: 'Hello from Vuex'}},mutations: {increment(state) {state.count++},updateMessage(state, newMessage) {state.message = newMessage}},actions: {async updateMessageAsync(context, newMessage) {// 模拟API请求await new Promise(resolve => setTimeout(resolve, 500))context.commit('updateMessage', newMessage)}},getters: {doubleCount(state) {return state.count * 2}}
})

在 main.js 中引入:

import { createApp } from 'vue'
import App from './App.vue'
import store from './store'createApp(App).use(store).mount('#app')

2. 核心概念

  • State:存储应用状态的数据源
  • Mutations:唯一可以修改 state 的同步函数
  • Actions:处理异步操作,通过 commit 调用 mutations
  • Getters:从 state 派生出的计算属性

3. 组件中使用

src/component/VuexPage1.vue

<template><div class="vuex-page1"><h2>Vuex Page 1</h2><p>Count from store: {{ $store.state.count }}</p><p>Double Count: {{ $store.getters.doubleCount }}</p><p>Message: {{ $store.state.message }}</p><button @click="$store.commit('decrement')">Decrement</button><button @click="$store.dispatch('increment')">Increment (via action)</button><button @click="updateMessage">Change Message</button></div>
</template><script setup>
import { useStore } from 'vuex'// 获取store实例
const store = useStore()// 组件方法
const updateMessage = () => {store.commit('updateMessage', 'Updated from Vuex Page 1')
}
</script><style scoped>
.vuex-page1 {padding: 20px;border: 1px solid #42b983;margin: 10px;background-color: #f0fdf4;
}button {margin: 0 5px;padding: 5px 10px;cursor: pointer;
}
</style>

src/component/VuexPage2.vue

<template><div class="vuex-page2"><h2>Vuex Page 2</h2><p>Count from store: {{ $store.state.count }}</p><p>Double Count: {{ $store.getters.doubleCount }}</p><p>Message: {{ $store.state.message }}</p><button @click="$store.commit('increment')">Increment</button><button @click="$store.commit('reset')">Reset Count</button><button @click="updateMessageAsync">Change Message (Async)</button></div>
</template><script setup>
import { useStore } from 'vuex'// 获取store实例
const store = useStore()// 组件方法
const updateMessageAsync = () => {store.dispatch('updateMessageAsync', 'Updated from Vuex Page 2 (Async)')
}
</script><style scoped>
.vuex-page2 {padding: 20px;border: 1px solid #3498db;margin: 10px;background-color: #f0f7ff;
}button {margin: 0 5px;padding: 5px 10px;cursor: pointer;
}
</style>

App.vue

<template><div id="app"><h1>Vuex Store Test</h1><VuexPage1 /><VuexPage2 /></div>
</template><script setup>
import VuexPage1 from './components/VuexPage1.vue'
import VuexPage2 from './components/VuexPage2.vue'
</script><style>
#app {font-family: Avenir, Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;text-align: center;color: #2c3e50;margin-top: 60px;
}
</style>

 4.效果展示

三、Pinia 的使用方法

Pinia 是 Vuex 的继任者,简化了状态管理的写法,天然支持 TypeScript,更符合 Vue 3 的 Composition API 风格。

1. 安装与配置

npm install pinia

创建 store/index.js:

import { createPinia } from 'pinia'
export default createPinia()

创建 store/counterStore.js:

import { defineStore } from 'pinia'export const useCounterStore = defineStore('counter', {state: () => ({count: 0,message: 'Hello from Pinia'}),actions: {increment() {this.count++},async updateMessageAsync(newMessage) {await new Promise(resolve => setTimeout(resolve, 500))this.message = newMessage}},getters: {doubleCount() {return this.count * 2}}
})

在 main.js 中引入:

import { createApp } from 'vue'
import App from './App.vue'
import store from './store'createApp(App).use(store).mount('#app')

2. 核心概念

  • Store:每个 store 都是一个独立的模块
  • State:存储状态的数据源
  • Actions:可以包含同步和异步操作,直接修改 state
  • Getters:计算属性,基于 state 派生

3. 组件中使用

src/component/Page1.vue

<template><div class="page1"><h2>Page 1</h2><p>Count from store: {{ counterStore.count }}</p><p>Message: {{ counterStore.message }}</p><button @click="counterStore.increment">Increment</button><button @click="counterStore.decrement">Decrement</button><button @click="counterStore.changeMultiplier(5)">changeMultiplier</button><button @click="beMultiplier">beMultiplier</button><button @click="changeMessage">Change Message</button></div>
</template><script setup>
import { useCounterStore } from '../store/counterStore'// 获取store实例
const counterStore = useCounterStore()// 组件方法
const changeMessage = () => {counterStore.updateMessage('Updated from Page 1')
}
const beMultiplier=()=>{counterStore.beMultipliedBy(4)
}
</script><style scoped>
.page1 {padding: 20px;border: 1px solid #ccc;margin: 10px;
}button {margin: 0 5px;padding: 5px 10px;
}
</style>

src/component/Page2.vue

<template><div class="page2"><h2>Page 2</h2><p>Count from store: {{ counterStore.count }}</p><p>Message: {{ counterStore.message }}</p><button @click="counterStore.increment">Increment</button><button @click="counterStore.reset">Reset Count</button><button @click="changeMessage">Change Message</button></div>
</template><script setup>
import { useCounterStore } from '../store/counterStore'// 获取store实例
const counterStore = useCounterStore()// 组件方法
const changeMessage = () => {counterStore.updateMessage('Updated from Page 2')
}
</script><style scoped>
.page2 {padding: 20px;border: 1px solid #666;margin: 10px;background-color: #f5f5f5;
}button {margin: 0 5px;padding: 5px 10px;
}
</style>

App.vue


<template><div id="app"><h1>Pinia Store Test</h1><Page1 /><Page2 /></div>
</template><script setup>
import Page1 from './components/Page1.vue'
import Page2 from './components/Page2.vue'
</script><style>
#app {font-family: Avenir, Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;text-align: center;color: #2c3e50;margin-top: 60px;
}
</style>

4. 效果展示

 

四、Pinia 与 Vuex 的核心区别

特性Vuex 4Pinia
模块化需要通过 modules 创建模块每个 store 都是独立模块,天然支持模块化
状态修改必须通过 mutations直接在 actions 中修改,或直接修改 state
异步操作需要在 actions 中处理可以在 actions 中直接处理
TypeScript 支持有限,需要额外类型定义原生支持,类型推断更友好
代码简洁性较繁琐,需要 commit/dispatch 区分更简洁,直接调用方法
开发者工具支持支持支持,且有更好的时间线追踪
插件系统丰富兼容 Vuex 的插件,且有新的插件系统

五、如何选择

  1. 新项目:优先选择 Pinia,它是 Vue 官方推荐的最新方案,API 更简洁,TypeScript 支持更好。

  2. 已有 Vuex 项目

    • 若项目稳定运行,无需急于迁移
    • 若进行重大重构,可考虑迁移到 Pinia
    • Vuex 4 仍会维护,但不会有新功能
  3. 团队因素:如果团队已熟悉 Vuex,且项目复杂度不高,继续使用 Vuex 也是合理选择。

六、总结

Pinia 和 Vuex 都是优秀的 Vue 状态管理方案,它们解决的核心问题相同,但实现方式有所不同。

Vuex 作为成熟的状态管理库,有着完善的生态和社区支持,适合需要严格规范状态修改流程的大型项目。而 Pinia 则代表了未来的发展方向,它简化了状态管理的写法,提供了更好的开发体验和 TypeScript 支持。

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

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

相关文章

OpenMed 项目深度分析:推动医疗 NLP 领域的开源革命

摘要 医疗人工智能(AI)领域因高质量数据和模型的获取受限而发展缓慢。OpenMed 项目通过开源超过380个医疗命名实体识别(NER)模型,显著降低了研究与应用门槛。本文从项目背景、技术优势、应用场景、实施挑战及未来展望五个方面,系统分析 OpenMed 的核心价值与潜力,揭示其…

大模型开发

什么是Ai&#xff1f;AI的全拼是(Artificial Intelligence)人工智能&#xff0c;使机器能够像人类一样思考、学习和解决问题的技术。在AI的应用情况下我们更多的是学习自然语言处理。在自然语言处理(Natural Language Processing&#xff0c;NLP)中&#xff0c;有一项关键技术叫…

【正常配置了beast扩展,phpinfo信息也显示了,但是就是不运行】

正常配置了beast扩展&#xff0c;phpinfo信息也显示了&#xff0c;但是就是不运行场景原因解决排查过程扩展场景 项目中使用到了beast进行源码保护&#xff0c;指定类存在&#xff0c;但是报错信息提示类找不到&#xff0c;beast扩展添加到了正在运行的php版本下的ext文件夹下…

CRMEB 单商户PRO多商户通用去版权教程

CRMEB去版权教程&#xff0c;此教程可根据具体版本进行调整&#xff0c;基本适用次方法。 后端版权修改 修改后端管理底部版权及门店后端管理底部版权。 文件位置 \view\admin\src\components\copyright\index.vue 文件位置 \view\admin\src\router\routes.js 文件位置 \vi…

旧物回收小程序系统开发:重塑旧物回收产业新生态

在传统观念中&#xff0c;旧物回收往往给人一种脏乱差、效率低下的印象&#xff0c;回收过程繁琐&#xff0c;回收渠道有限&#xff0c;导致许多可回收物被浪费。然而&#xff0c;随着信息技术的飞速发展&#xff0c;旧物回收小程序系统的开发正为这一古老行业带来前所未有的变…

SSE和WebSocket区别到底是什么

文章目录SSE 与 WebSocket&#xff1a;深入剖析两者核心差异核心差异&#xff1a;单向 vs. 双向通信技术细节对比协议与连接数据格式错误处理与可靠性适用场景&#xff1a;何时选择 SSE&#xff0c;何时选择 WebSocket&#xff1f;总结SSE 与 WebSocket&#xff1a;深入剖析两者…

西安电子科技大学金融学431考研经历分享

考研数学是区分度最大的科目之一&#xff0c;如何高效备考&#xff1f;本文为你推荐多位名师和经典书籍&#xff0c;助你在每个阶段都能稳步提升&#xff0c;最终冲刺成功。一、考研数学备考策略教师推荐① 高等数学&#xff1a;② 线性代数&#xff1a;③ 概率论与数理统计&am…

laravel RedisException: Connection refused优雅草PMS项目管理系统报错解决-以及Redis 详细指南-优雅草卓伊凡

laravel RedisException: Connection refused优雅草PMS项目管理系统报错解决-以及Redis 详细指南-优雅草卓伊凡今天来开始更新pms系统&#xff0c;因为我们ppt上面要做&#xff0c;才发现原来打不开&#xff0c;此前主要是事情太多&#xff0c;我们一直有很多东西搁置解决 Lara…

拉力覆冰在线监测装置:电力线路安全运行的数字化守卫者

在极端天气频发的背景下&#xff0c;输电线路覆冰灾害已成为威胁电网稳定运行的关键因素。拉力覆冰在线监测装置通过数字化技术构建起全天候监测体系&#xff0c;为电力运维提供精准数据支撑。本文从技术实现与实际应用价值角度&#xff0c;解析该装置的核心功能与行业意义。核…

AI面试如何提升物流行业招聘效率?实战案例解析

每年秋招季&#xff0c;物流行业都会迎来海量应届生简历涌入。面对业务快速扩张与人才筛选压力&#xff0c;传统线下面试流程长、标准模糊、成本高昂等问题愈发凸显。本文通过两大物流头部企业的实战案例&#xff0c;解析AI面试如何破解招聘困局&#xff0c;实现效率与质量的双…

【机器学习】组合优化问题combination-optimization概述

博主简介&#xff1a;努力学习的22级计算机科学与技术本科生一枚&#x1f338;博主主页&#xff1a; Yaoyao2024往期回顾&#xff1a;【二分图算法】手把手教你学会&#xff1a;染色法&#xff08;判断二分图&#xff09;、匈牙利算法&#xff08;二分图的最大匹配&#xff09;…

Linux网络编程-osi、udp

网络&#xff1a;不同主机&#xff0c;进程间通信达到不同主机之间的困难&#xff1a;解决主机之间的硬件层面的互联互通解决主机之间的软件层面的互联互通广域网&#xff1a;进行大范围网络数据交换IP地址&#xff1a;区分不同主机 唯一的&#xff08;软件地址&#xff09;MAC…

删除 XML 格式中双引号内的空格

要使用 Shell 命令删除 XML 格式中双引号内的空格&#xff08;仅处理属性值中的空格&#xff0c;保留标签外的空格&#xff09;&#xff0c;可以使用以下 sed 命令&#xff1a; sed -i :loop; s/\("[^"]*\) \([^"]*"\)/\1\2/g; t loop filename.xml命令详解…

电脑声音修复?【图文详解】电脑没有声音?声音异常

一、问题背景 在使用电脑的过程中&#xff0c;声音异常是很常见的问题。比如明明打开了音频文件&#xff0c;却听不到任何声音&#xff1b;或者声音忽大忽小、伴有杂音&#xff1b;或者更新了声卡驱动后&#xff0c;电脑播放不了声音了&#xff1b;还有可能是插入耳机后&#x…

【文献笔记】ARS: Automatic Routing Solver with Large Language Models

ARS: Automatic Routing Solver with Large Language Models https://github.com/Ahalikai/ARS-Routbench/ ARS&#xff1a;基于大语言模型的自动路由求解器 1. 概述 1.1. 研究背景 车辆路径问题&#xff08;VRP&#xff09;是一类经典的组合优化问题&#xff0c;广泛应用于…

RK3568笔记九十:基于web显示RTSP流

若该文为原创文章,转载请注明原文出处。 在网上看到个方案,使用web显示RTSP视频流,思路是前端传入RTSP地址,cgi通过FFMPEG接收RTSP流并保存成avi文件,在通过ffmpeg 命令把avi文件保存成mp4文件,前端在播放mp4文件。此方案需要先保存文件,在转换文件,无法实时播放。 所以…

2025年Flutter开发主流技术栈

2025年Flutter开发主流技术栈 Flutter作为一种高效、跨平台的移动应用开发框架&#xff0c;近年来在开发者社区中越来越受欢迎。以下是2025年Flutter开发的主流技术栈&#xff0c;涵盖了从核心框架到开发工具、状态管理、数据存储等多个方面。 1. 核心框架 Flutter&#xff1a;…

Qt 常用控件 - 1

控件概述 编程讲究的是 --- 站在巨人的肩膀上 --- 不是编写一个图形化界面上的内容 --- Qt 已经提供了很多控件了&#xff01;&#xff01;&#xff01;提高图形化界面的开发效率&#xff01;&#xff01;&#xff01;重点变成我们怎么使用这些已有的控件&#xff01; Widge…

springdoc-openapi-ui的使用教程

<dependency><groupId>org.springdoc</groupId><artifactId>springdoc-openapi-ui</artifactId><version>1.6.14</version> </dependency>springdoc-openapi-ui 是一个用于生成 OpenAPI 文档的库&#xff0c;它与 Swagger 的关…

【硬件-笔试面试题】硬件/电子工程师,笔试面试题-3,(运放/三极管)

目录 1、题目 2、解答 【硬件-笔试面试题】硬件/电子工程师&#xff0c;笔试面试题-3&#xff0c;&#xff08;运放/三极管&#xff09; 这是一道大疆的笔试题 1、题目 2、解答