Pinia 实战教程:构建高效的 Vue 3 状态管理系统
前言
在前端开发中,状态管理已成为必不可少的一部分,Vue.js 生态系统中提供了多种状态管理解决方案。Pinia 是 Vue 3 推出的一种全新的状态管理库,旨在取代 Vuex,提供更简洁的 API、更优雅的 TypeScript 支持以及更高效的性能表现。
本篇文章将深入探讨 Pinia 的核心概念和实际应用,帮助开发者在 Vue 项目中更好地管理全局状态。
什么是 Pinia?
Pinia 是 Vue.js 新一代的状态管理库,它从 Vue 3 开始推出,旨在取代 Vuex。Pinia 提供了更简单的 API 和更好的性能,使得状态管理变得更加容易和高效。
为什么选择 Pinia?
更简单的 API
Pinia 的 API 很简洁,学习成本低。它采用了更符合直觉的设计,使得开发者可以更快地上手。
TypeScript 友好
Pinia 对 TypeScript 提供了很好的支持。你可以轻松地在 Vue 3 项目中使用 TypeScript,让你的代码更具可读性和可维护性。
性能更佳
Pinia 在性能方面做了许多优化。相比 Vuex,它产生的开销更小,运行速度更快。
使用步骤
1. 如何安装 Pinia?
首先,你需要在你的 Vue 3 项目中安装 Pinia。你可以使用 npm 或 yarn 进行安装:
npm install pinia
# 或者
yarn add pinia
安装完成后,你需要在你的 Vue 根实例中引入并使用 Pinia:
import { createApp } from 'vue';
import { createPinia } from 'pinia';
import App from './App.vue';const app = createApp(App);
const pinia = createPinia();app.use(pinia);
app.mount('#app');
2. 创建一个 Pinia Store
在 Pinia 中,状态管理的核心是 Store。你可以把 Store 看作是一个全局的对象,它包含了你的应用状态、操作状态的方法和计算属性。
创建一个 Store
首先,我们来创建一个简单的 Store。新建一个 store 文件夹,然后在里面新建一个 index.js 文件:
import { defineStore } from 'pinia';export const useCounterStore = defineStore('counter', {state: () => ({count: 0}),actions: {increment() {this.count++;},decrement() {this.count--;}},getters: {doubleCount: (state) => state.count * 2}
});
在这个 Store 中,我们定义了一个 count 状态,两个操作状态的方法 increment 和 decrement,以及一个计算属性 doubleCount。
使用 Store
现在,我们来看看如何在组件中使用这个 Store。
<template><div><p>Count: {{ counter.count }}</p><p>Double Count: {{ counter.doubleCount }}</p><button @click="counter.increment">Increment</button><button @click="counter.decrement">Decrement</button></div>
</template><script>
import { useCounterStore } from '../store';export default {setup() {const counter = useCounterStore();return { counter };}
}
</script>
在这个组件中,我们通过 useCounterStore 函数来访问 Store,并绑定到模板中。通过调用 increment 和 decrement 方法,我们可以修改状态,并且计算属性 doubleCount 也会自动更新。
进阶用法
接下来我们来深入探讨 Pinia 的一些进阶用法,包括模块化 Store、插件以及如何与 Vue Router 一起使用。
1. 模块化 Store
在实际的项目中,通常会有很多状态需要管理,为了保持代码的清晰和可维护性,我们可以将不同的状态分成不同的模块。
创建模块化 Store
假设我们正在开发一个电商网站,我们可以创建一个用户模块和一个购物车模块。首先,新建一个 stores 文件夹,然后在里面新建两个文件:user.js 和 cart.js。
user.js 文件内容:
import { defineStore } from 'pinia';export const useUserStore = defineStore('user', {state: () => ({name: '',isLoggedIn: false}),actions: {login(name) {this.name = name;this.isLoggedIn = true;},logout() {this.name = '';this.isLoggedIn = false;}}
});
cart.js 文件内容:
import { defineStore } from 'pinia';export const useCartStore = defineStore('cart', {state: () => ({items: []}),actions: {addItem(item) {this.items.push(item);},removeItem(index) {this.items.splice(index, 1);}}
});
使用模块化 Store
在组件中使用这些模块化的 Store 与之前的方法类似:
<template><div><p v-if="user.isLoggedIn">Hello, {{ user.name }}</p><p v-else>Please log in</p><button @click="user.isLoggedIn ? user.logout() : user.login('John')">{{ user.isLoggedIn ? 'Logout' : 'Login' }}</button><hr /><div><h3>Cart</h3><ul><li v-for="(item, index) in cart.items" :key="index">{{ item }} <button @click="cart.removeItem(index)">Remove</button></li></ul><button @click="cart.addItem('New Item')">Add Item</button></div></div>
</template><script>
import { useUserStore } from '../stores/user';
import { useCartStore } from '../stores/cart';export default {setup() {const user = useUserStore();const cart = useCartStore();return { user, cart };}
}
</script>
在这个示例中,我们同时使用了用户和购物车两个 Store,并在组件中根据业务逻辑操作它们。
2. 使用 Pinia 插件
Pinia 强大的一个特性是它支持插件。如果你需要扩展 Pinia 的功能,可以通过编写和使用插件来实现。
创建一个简单的插件
假设我们要创建一个记录所有 state 变化日志的插件,首先定义插件函数:
const loggerPlugin = (context) => {context.store.$subscribe((mutation, state) => {console.log('State changed:', mutation, state);});
};然后,在创建 Pinia 实例时,使用这个插件:
import { createApp } from 'vue';
import { createPinia } from 'pinia';
import App from './App.vue';
import loggerPlugin from './plugins/logger';const app = createApp(App);
const pinia = createPinia();pinia.use(loggerPlugin);app.use(pinia);
app.mount('#app');
这样,每当你修改 Store 的状态时,都会在控制台输出相关日志信息。
3. 与 Vue Router 一起使用
Pinia 可以轻松地与 Vue Router 集成,提供更强大的状态管理和路由控制。
示例:基于状态的路由控制
假设我们要实现一个只有登录用户才能访问的页面:
首先,定义路由器:
import { createRouter, createWebHistory } from 'vue-router';
import Home from './views/Home.vue';
import Dashboard from './views/Dashboard.vue';
import { useUserStore } from './stores/user';const routes = [{ path: '/', component: Home },{ path: '/dashboard', component: Dashboard, meta: { requiresAuth: true } }
];const router = createRouter({history: createWebHistory(),routes
});router.beforeEach((to, from, next) => {const userStore = useUserStore();if (to.meta.requiresAuth && !userStore.isLoggedIn) {next('/');} else {next();}
});export default router;
然后,在你的应用中使用路由器:
import { createApp } from 'vue';
import { createPinia } from 'pinia';
import App from './App.vue';
import router from './router';const app = createApp(App);
const pinia = createPinia();app.use(pinia);
app.use(router);
app.mount('#app');
这样,我们实现了一个只有登录用户才能访问的 Dashboard 页面。如果用户未登录,则会被重定向到首页。
总结
Pinia 作为 Vue.js 新一代的状态管理工具,凭借其简洁的 API、优异的 TypeScript 支持和高效的性能,逐渐成为 Vue 3 项目中的理想选择。通过本教程,我们详细介绍了 Pinia 的基本用法及其进阶功能,包括模块化 Store、插件机制和与 Vue Router 的集成。希望这些内容能够帮助你更好地理解和应用 Pinia,从而提升开发效率和代码的可维护性。
相关文章:
Pinia 实战教程:构建高效的 Vue 3 状态管理系统
前言 在前端开发中,状态管理已成为必不可少的一部分,Vue.js 生态系统中提供了多种状态管理解决方案。Pinia 是 Vue 3 推出的一种全新的状态管理库,旨在取代 Vuex,提供更简洁的 API、更优雅的 TypeScript 支持以及更高效的性能表现…...

springboot3如何集成knife4j 4.x版本及如何进行API注解
1. 什么是Knife4j knife4j是为Java MVC框架集成Swagger生成Api文档的增强解决方案, 取名knife4j是希望她能像一把匕首一样小巧,轻量,并且功能强悍!knife4j的前身是swagger-bootstrap-ui,swagger-bootstrap-ui自1.9.6版本后,正式更名为knife4j为了契合微服务的架构发展,由于原来…...
区块链讲解
区块链技术是一种分布式账本技术,其应用场景和优势可以总结如下: 金融服务:区块链可以用于支付、跨境汇款、证券交易、贷款等金融服务领域,通过去中心化的方式实现快速、低成本、安全的交易。 物联网:区块链可以用于物…...

使用eclipse构建SpringBoot项目
我这里用eclipse2018版本做演示,大家有需要的可以下载Eclipse Downloads | The Eclipse Foundation 1.打开eclipse,选择存放代码的位置 2.选择 file >> new >> project >> 选择springboot文件下的 spring starter project 2.这里选择N…...
uniapp input限制输入负数,以及保留小数点两位.
简单处理的方式 限制输入负数,以及保留小数点两位.: <input type"number" placeholder"请输入" v-model"num"input"numnum.toString().replace(/\-/g,).match(/^\d(?:\.\d{0,2})?/)" /> 可以输入负数,保留两位小数点,把rep…...
《FreeRTOS任务删除篇》
任务删除函数 源码1. 进入临界区1.1 第一步1.2 第二步1.3 第三步1.4 第四步 2. 获取待删除任务的任务控制块TCB3. 从就绪/延迟列表中删除任务4. 从事件列表中删除任务5. 如果待删除任务是当前运行的任务6. 如果待删除任务是其它任务7. 退出临界区7.1 第一步7.2 第二步7.3 第三步…...

递归算法专题一>Pow(x, n)
题目: 解析: 代码: public double myPow(double x, int n) {return n < 0 ? 1.0 / pow(x,-n) : pow(x,n); }private double pow(double x, int n){if(n 0) return 1.0;double tmp pow(x,n / 2);return n % 2 0 ? tmp * tmp : tmp …...

数据结构第一讲
数据结构定义 算法的定义 什么是好算法? 空间复杂度 时间复杂度 例子1 打印1到N之间的正整数 有递归和循环两种方法实现。 但是在数字变大后,递归的方法会导致内存占用过多而崩溃。 而循环则不会 例子2 写程序给定多项式在X处的值 从里往外算的算…...
SHELL笔记(循环)
在 Shell 编程中,循环结构是极为重要的一部分,它能够让我们轻松地重复执行特定的代码块,从而高效地处理各种重复性任务。本文将详细介绍 Shell 中常见的循环结构,包括 for 循环、while 循环和 until 循环,并通过具体的…...

SpringBoot多文件上传
多文件上传是在单文件上传的基础上修改而来,不了解单文件上传可以参考上一篇。以下在将修改部分展示如下: 一、修改upload.html文件: <!DOCTYPE html> <html> <head> <meta charset"UTF-8"> <title&g…...

MyBatis-数据库连接池、属性文件config.properties、类名简化、MyBatis的整体架构
一、数据库连接池 1、概述 存储实现创建好的连接对象的容器 2、优点 避免了频繁创建和销毁连接对象 3、使用 在使用到连接对象时可在数据库连接池中直接获取 4、实现 不需要我们去实现,框架和一些第三方有现成的组件(C3P0、ADCP、德鲁伊(阿里巴巴)ÿ…...

Flink-Source的使用
Data Sources 是什么呢?就字面意思其实就可以知道:数据来源。 Flink 做为一款流式计算框架,它可用来做批处理,也可以用来做流处理,这个 Data Sources 就是数据的来源地。 flink在批/流处理中常见的source主要有两大类…...

C0031.在Clion中使用mingw编译器来编译opencv的配置方法
mingw编译器编译opencv库的配置方法...
Android——连接MySQL(Java版)
Android——连接MySQL(Java版) 目录: Android——连接MySQL(Java版)一、JDBC1、什么是JDBC2、载入JDBC3、创建JDBC的工具类 二、使用数据库 一、JDBC 1、什么是JDBC JDBC全称Java Database Connectivity,译为Java语言连接数据库,是sun公司制…...
「四」体验HarmonyOS端云一体化开发模板——工程目录结构与云侧工程一键部署AGC云端
关于作者 白晓明 宁夏图尔科技有限公司董事长兼CEO、坚果派联合创始人 华为HDE、润和软件HiHope社区专家、鸿蒙KOL、仓颉KOL 华为开发者学堂/51CTO学堂/CSDN学堂认证讲师 开放原子开源基金会2023开源贡献之星 「目录」 「一」HarmonyOS端云一体化概要 「二」体验HarmonyOS端云一…...
Kotlin:后端开发的新宠
在当今的软件开发领域,编程语言的选择对于项目的成功至关重要。Kotlin,一种由 JetBrains 开发的编程语言,近年来在后端领域逐渐崭露头角,展现出了广阔的应用前景。 一、Kotlin 简介 Kotlin 是一种基于 JVM(Java Virt…...

SSM全家桶 1.Maven
或许总要彻彻底底地绝望一次 才能重新再活一次 —— 24.11.20 maven在如今的idea中已经实现自动配置,不需要我们手动下载 一、Maven的简介和快速入门 Maven 是一款为 Java 项目构建管理、依赖管理的工具(软件),使用 Maven 可以自动化构建测试、打包和发…...

SpringBoot 集成 html2Pdf
一、概述: 1. springboot如何生成pdf,接口可以预览可以下载 2. vue下载通过bold如何下载 3. 一些细节:页脚、页眉、水印、每一页得样式添加 二、直接上代码【主要是一个记录下次开发更快】 模板位置 1. 导入pom包 <dependency><g…...
利用 Watchtower 自动监听并更新正在运行的 Docker 容器
本文首发于只抄博客,欢迎点击原文链接了解更多内容。 前言 大部分 VPS 和 NAS 用户或多或少都有用 Docker 来部署一些 Self-hosting 的服务,其中大部分项目都是开源项目,更新频率非常高,特别是一些版本 0.x 的项目,及…...

Nodejs开发仿马蜂窝旅游小程序API接口,服务器端开发,商家后台 Vue3+微信小程序+koa+mongodb+node.js
文章目录 🚀 开启您的互联网创业新篇章一、🔥 课程亮点:二、🌐 适合人群:学习这个课程后,您将会收获到三、旅游后台管理系统1.后台登录界面2.后台首页 四、前台旅游小程序1.首页展示2.目的地界面3.搜索功能…...

STM32F4基本定时器使用和原理详解
STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...

相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...

Linux-07 ubuntu 的 chrome 启动不了
文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了,报错如下四、启动不了,解决如下 总结 问题原因 在应用中可以看到chrome,但是打不开(说明:原来的ubuntu系统出问题了,这个是备用的硬盘&a…...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...

Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...

HDFS分布式存储 zookeeper
hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架,允许使用简单的变成模型跨计算机对大型集群进行分布式处理(1.海量的数据存储 2.海量数据的计算)Hadoop核心组件 hdfs(分布式文件存储系统)&a…...

Docker 本地安装 mysql 数据库
Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker ;并安装。 基础操作不再赘述。 打开 macOS 终端,开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...

C++:多态机制详解
目录 一. 多态的概念 1.静态多态(编译时多态) 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1).协变 2).析构函数的重写 5.override 和 final关键字 1&#…...
Webpack性能优化:构建速度与体积优化策略
一、构建速度优化 1、升级Webpack和Node.js 优化效果:Webpack 4比Webpack 3构建时间降低60%-98%。原因: V8引擎优化(for of替代forEach、Map/Set替代Object)。默认使用更快的md4哈希算法。AST直接从Loa…...