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.搜索功能…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...
【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...
Typeerror: cannot read properties of undefined (reading ‘XXX‘)
最近需要在离线机器上运行软件,所以得把软件用docker打包起来,大部分功能都没问题,出了一个奇怪的事情。同样的代码,在本机上用vscode可以运行起来,但是打包之后在docker里出现了问题。使用的是dialog组件,…...
Linux离线(zip方式)安装docker
目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1:修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本:CentOS 7 64位 内核版本:3.10.0 相关命令: uname -rcat /etc/os-rele…...
基于IDIG-GAN的小样本电机轴承故障诊断
目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) 梯度归一化(Gradient Normalization) (2) 判别器梯度间隙正则化(Discriminator Gradient Gap Regularization) (3) 自注意力机制(Self-Attention) 3. 完整损失函数 二…...
离线语音识别方案分析
随着人工智能技术的不断发展,语音识别技术也得到了广泛的应用,从智能家居到车载系统,语音识别正在改变我们与设备的交互方式。尤其是离线语音识别,由于其在没有网络连接的情况下仍然能提供稳定、准确的语音处理能力,广…...
人工智能 - 在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型
在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型。这些平台各有侧重,适用场景差异显著。下面我将从核心功能定位、典型应用场景、真实体验痛点、选型决策关键点进行拆解,并提供具体场景下的推荐方案。 一、核心功能定位速览 平台核心定位技术栈亮…...
从零开始了解数据采集(二十八)——制造业数字孪生
近年来,我国的工业领域正经历一场前所未有的数字化变革,从“双碳目标”到工业互联网平台的推广,国家政策和市场需求共同推动了制造业的升级。在这场变革中,数字孪生技术成为备受关注的关键工具,它不仅让企业“看见”设…...
Redis上篇--知识点总结
Redis上篇–解析 本文大部分知识整理自网上,在正文结束后都会附上参考地址。如果想要深入或者详细学习可以通过文末链接跳转学习。 1. 基本介绍 Redis 是一个开源的、高性能的 内存键值数据库,Redis 的键值对中的 key 就是字符串对象,而 val…...
