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.搜索功能…...
观成科技:隐蔽隧道工具Ligolo-ng加密流量分析
1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具,该工具基于TUN接口实现其功能,利用反向TCP/TLS连接建立一条隐蔽的通信信道,支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式,适应复杂网…...
大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...
中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试
作者:Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位:中南大学地球科学与信息物理学院论文标题:BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接:https://arxiv.…...
(二)TensorRT-LLM | 模型导出(v0.20.0rc3)
0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...
关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...
渲染学进阶内容——模型
最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...
CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...
QT3D学习笔记——圆台、圆锥
类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体(对象或容器)QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质(定义颜色、反光等)QFirstPersonC…...
使用LangGraph和LangSmith构建多智能体人工智能系统
现在,通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战,比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...
Go 并发编程基础:通道(Channel)的使用
在 Go 中,Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式,用于在多个 Goroutine 之间传递数据,从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...
