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.搜索功能…...
Vue记事本应用实现教程
文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展:显示创建时间8. 功能扩展:记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...
内存分配函数malloc kmalloc vmalloc
内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...

【Oracle APEX开发小技巧12】
有如下需求: 有一个问题反馈页面,要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据,方便管理员及时处理反馈。 我的方法:直接将逻辑写在SQL中,这样可以直接在页面展示 完整代码: SELECTSF.FE…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了: 这一篇我们开始讲: 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下: 一、场景操作步骤 操作步…...
线程与协程
1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指:像函数调用/返回一样轻量地完成任务切换。 举例说明: 当你在程序中写一个函数调用: funcA() 然后 funcA 执行完后返回&…...

CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)
本文把滑坡位移序列拆开、筛优质因子,再用 CNN-BiLSTM-Attention 来动态预测每个子序列,最后重构出总位移,预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵(S…...