Vue3下pinia的状态管理原理和具体使用示例

2023-11-12

一、Pinia是什么?

Pinia在Composition API的设计背景下,以Vuex下一代的构想设计了新的Vue存储状态管理库;Pinia 是一个基于 Vue 3 的状态管理库,它提供了一个可组合的、类型安全的 API 来管理 Vue 应用程序的状态。

二、Pinia的特性

  • 支持vue2选项式api和vue3组合式api写法
  • Pinia没有mutations,只有:state、getters、actions
  • Pinia分模块不需要modules(vuex分模块需要modules)
  • TypeScript支持很好
  • Pinia体积更小,性能更好
  • Pinia可以在组件中直接修改state中的数据
  • Pinia在actions中支持异步操作

三、Pinia在Vue3中的使用

首先,Vue3是Vue框架的最新版本,它带来了很多新的特性和改进,其中一个最重要的改进就是它的响应式系统变得更加高效和灵活。而pinia则是一个基于Vue3的状态管理库,它的设计理念是简单、轻量、可测试和可扩展。

在Vue3中,响应式系统的核心是通过ES6的“Proxy”代理实现响应,通过代理、反射等特性可以让我们更加方便地监视和拦截对象的属性访问和修改,从而实现了响应式的效果。而Pinia的工作原理主要是利用了Vue 3提供的reactive函数和watch函数。当状态存储中的状态发生变化时,Pinia会自动更新依赖于该状态的组件。在组件中,可以使用computed和watch函数来监听状态存储中的状态,当状态发生变化时,组件会自动更新。

具体来说,在pinia中,我们可以定义一个“store”,它是一个包含了一些状态和一些操作这些状态的方法的对象。在这个store中,我们可以使用Vue3的响应式系统来定义状态,比如:

import { defineStore } from 'pinia'

export const useCounterStore = defineStore({
  id: 'counter',
  state: () => ({
    count: 0
  }),
  actions: {
    increment() {
      this.count++
    }
  }
})

在这个例子中,我们定义了一个名为“useCounterStore”的store,它包含了一个名为“count”的状态和一个名为“increment”的方法。我们可以通过“useCounterStore.count”来访问这个状态,通过“useCounterStore.increment()”来调用这个方法。

需要注意的是,在pinia中,所有的状态都是只读的,我们只能通过定义的方法来修改它们。这样可以确保状态的一致性和可追溯性。

四、如何在Vue3中使用pinia进行状态管理

首先,我们需要安装pinia:

npm install pinia

然后,在我们的Vue应用中,我们需要创建一个名为“pinia”的实例,并在根组件中把它挂载到Vue实例上,这样我们的应用的所有组件就可以使用它了。具体的代码如下:

import { createPinia } from 'pinia'
import { createApp } from 'vue'
import App from './App.vue'

const pinia = createPinia()
const app = createApp(App)

app.use(pinia)
app.mount('#app')

接着,我们就可以开始定义我们的store了。我们可以通过“defineStore”函数来定义一个store,它接受一个包含了store的id、state和actions的对象。其中,id是store的唯一标识符,state是一个函数,返回一个包含了store的状态的对象,actions是一个包含了store的操作状态的方法的对象。具体的代码如下:

import { defineStore } from 'pinia'

export const useCounterStore = defineStore({
  id: 'counter',
  state: () => ({
    count: 0
  }),
  actions: {
    increment() {
      this.count++
    }
  }
})

在store中,我们可以使用Vue3的响应式系统来定义状态,并且通过定义的方法来操作这些状态。需要注意的是,在pinia中,所有的状态都是只读的,我们只能通过定义的方法来修改它们。

最后,在我们的组件中,我们可以使用“useStore”函数来获取我们定义的store,并在组件中使用它。具体的代码如下:

import { useStore } from 'pinia'
import { defineComponent } from 'vue'

export default defineComponent({
  setup() {
    const counterStore = useStore('counter')

    function handleClick() {
      counterStore.increment()
    }

    return {
      count: counterStore.count,
      handleClick
    }
  }
})

在这个例子中,我们使用“useStore”函数来获取我们定义的名为“counter”的store,并在组件中使用它。通过“counterStore.count”来获取store中的状态,通过“counterStore.increment()”来调用store中的方法。

五、pinia状态管理的高级用法

1. Getter/Setter函数

首先,pinia支持“getter”和“setter”函数,可以让我们更加灵活地定义状态的访问和修改方式。具体的代码如下:

import { defineStore } from 'pinia'

export const useCounterStore = defineStore({
  id: 'counter',
  state: () => ({
    _count: 0
  }),
  getters: {
    count: state => state._count,
    doubleCount: state => state._count * 2
  },
  actions: {
    increment() {
      this._count++
    }
  }
})

在这个例子中,我们定义了一个名为“count”的getter函数和一个名为“doubleCount”的getter函数,它们分别返回状态“_count”的值和它的两倍。我们可以通过“counterStore.count”和“counterStore.doubleCount”来获取它们的返回值。

2. Actions函数和异步支持

另外,pinia还支持“actions”函数,它们可以让我们更加细粒度地控制状态的修改和异步操作。具体的代码如下:

import { defineStore } from 'pinia'

export const useCounterStore = defineStore({
  id: 'counter',
  state: () => ({
    _count: 0
  }),
  getters: {
    count: state => state._count,
    doubleCount: state => state._count * 2
  },
  actions: {
    increment() {
      this._count++
    },
    async incrementAsync() {
      await new Promise(resolve => setTimeout(resolve, 1000))
      this._count++
    }
  },
})

在这个例子中,我们定义了一个名为“increment”的“actions”函数和一个名为“incrementAsync”的异步“actions”函数,它们分别用来同步和异步增加状态“_count”的值。

3. Subscribe函数订阅状态变化

另外,pinia还支持“subscribe”函数,它可以让我们订阅状态的变化,并在状态变化时执行一些操作。具体的代码如下:

import { defineStore } from 'pinia'
export const useCounterStore = defineStore({
  id: 'counter',
  state: () => ({
    _count: 0
  }),
  getters: {
    count: state => state._count,
    doubleCount: state => state._count * 2
  },
  actions: {
    increment() {
        this._count++
    }
  }
})

//****** subscribe ********
const counterStore = useCounterStore()
counterStore.subscribe(({ count }) => {
  console.log(`count is now ${count}`)
})

在这个例子中,我们使用“subscribe”函数来订阅状态的变化,并在状态变化时打印一条日志。

4. Pinia持久化存储

为什么要做持久化?因为数据一刷新就回到了初始化的状态,希望能够保持数据的长久存储

  • 方式一:自己手动去写,使用localStorage或者sessionStorage
  • 方式二:使用插件,这里主要讲的是方式二

插件的持久化存储默认走的是sessionStorage

安装插件

npm i pinia-plugin-persist --save

注册插件

import { createPinia } from 'pinia'
const store = createPinia()
import piniaPluginPersist from 'pinia-plugin-persist' // 引入持久化存储插件
store.use(piniaPluginPersist) // 使用插件
export default store

开启持久化

import { defineStore } from 'pinia'
export const user = defineStore({
    id: 'user',
    state: () => {
        return {
            nickName: '张三用户',
            age: 18
        }
    },
    actions: {
        changeAge(val) {
            this.age += val
        }
    },
    
    // 开启数据缓存 --- localStorage
    // 数据默认存在sessionStorage里,并且会以store的id作为key
    persist: {
        enabled: true,
        strategies: [{
            key: 'my_user',
            storage: localStorage,
            paths: ['age'] // 如果不写paths,默认当前模块全部做持久化存储,如果写了,表示数组内的state做持久化存储。大白话:这个模块只有age做持久化存储
        }]
    }
})

总的来说,pinia提供了非常多的高级用法,可以让我们更加灵活和细粒度地控制状态管理的行为。如果你需要更加复杂的状态管理功能,pinia是一个非常不错的选择。

参考:Pinia的使用_木森林哥哥

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Vue3下pinia的状态管理原理和具体使用示例 的相关文章

  • angularjs:如何向资源对象添加缓存?

    在 http 中添加缓存非常简单 通过传递cache true http docs angularjs org api ng http https docs angularjs org api ng service 24http有缓存选项
  • Oo 任何 IDE 中的 javascript 代码补全

    你知道有什么IDE可以自动完成这种代码吗 我这里有一个 javascript 类生成器 function var core bind function method scope if method instanceof Function t
  • React-native:将场景绑定到导航栏

    我正在整理这个提问 回答应用程序 并遇到了这个障碍 我想从导航栏触发场景中的功能 与登录应用程序类似 我在导航栏中有一个用于提交答案的按钮 RightButton route navigator index navState if rout
  • 如何将udp发送到udp node.js服务器?

    我对此很陌生 所以我真的不知道我在做什么 但我已经设置了一个 node js udp 服务器 我想从客户端 来自网站 向它发送一个数据包 但我不知道如何在 javascript 中做到这一点 或者是否可能 我不是在研究如何从 Node js
  • 取消html5浏览器中的单图请求

    我正在动态加载 大 图像以绘制到 html5 画布中 如下所示 var t new Image t onload t src http myurl 但每隔一段时间就会想取消图片请求完全地 我想出的唯一方法是设置src to i e t sr
  • jquery 验证错误位置

    这看起来很简单 但我无法弄清楚 我正在使用 jquery 验证插件 我验证所有文件 但我想要的是在输入文本行中显示验证消息警报 例如在电子邮件输入中 请填写电子邮件地址 但现在它出现在所有字段下 在我的html中
  • 如何使用 jest 模拟第三方库

    我正在开发一个node js应用程序使用nestjs我有一堂课叫LoggerService如下 export class LoggerService private logger Rollbar constructor this logge
  • 是否可以使用 javascript 测试用户的浏览器/操作系统是否支持给定类型的链接?

    是否可以使用 javascript 或其他任何东西 测试用户的操作系统 浏览器是否支持给定的 url 方案 例如 大多数仅使用网络邮件的用户计算机上未设置 mailto 是否有可能以某种方式捕获单击 mailto 链接的尝试并弹出比浏览器错
  • HTML2canvas 和 Canvas2image,下载的屏幕截图不显示我的 HTML 图像

    我一直在开发一个 HTML 页面 我想将其转换为图像 我一直在使用 html2canvas 和 canvas2image 脚本并采用此代码http jsfiddle net 8ypxW 3 http jsfiddle net 8ypxW 3
  • 通过 node-http-proxy 保留基于 cookie 的会话

    我有一个简单的基于 Express 的 Node js Web 服务器 用于开发 JavaScript 应用程序 我将服务器设置为使用 node http proxy 来代理应用程序向在不同域和端口上运行的 Jetty 服务器发出的 API
  • Google Chrome 106 可拖动导致元素消失

    使用拖放元素时 绝对定位元素中包含的大多数其他元素都会从屏幕上消失 如果我调整窗口大小 这些元素会出现 但在开始拖动时会再次消失 我在最新版本的 Google Chrome 106 和 Beta 版本 107 0 5304 18 以及现在的
  • 使用 JS 合并具有相同值的相邻 HTML 表格单元格

    我已经为此苦苦挣扎了一段时间 我有一个根据一些 JSON 数据自动生成的表 该数据可能会有所不同 我想合并第一列中具有相同值的相邻单元格 例如此表中的 鱼 和 鸟 table tr td fish td td salmon td tr tr
  • 如何使JavaScript函数在Eclipse“大纲视图”中可见?

    我有这样的代码 但如果它在匿名函数中定义 则无法打开函数大纲 类没有问题 我该如何概述something2 请分享一些提示 我可以将所有函数标记为构造函数 但这是无效的方法 start of track event required deb
  • IE11不监听MSFullscreenChange事件

    我正在尝试使用 Bigscreen js 在 IE11 中使用全屏 但 IE11 不监听 MS FullscreenChange 事件 document addEventListener MSFullscreenChange functio
  • 将 javascript 整数转换为字节数组并返回

    function intFromBytes x var val 0 for var i 0 i lt x length i val x i if i lt x length 1 val val lt lt 8 return val func
  • Chartjs刻度标签位置

    尝试让 Y 轴刻度标签看起来像image https i stack imgur com XgoxX png 位于秤顶部且不旋转 缩放选项当前如下所示 scales yAxes id temp scaleLabel display true
  • 查询为空 Node Js Sequelize

    我正在尝试更新 Node js 应用程序中的数据 我和邮递员测试过 我的开发步骤是 从数据库 MySQL 获取ID为10的数据进行更新 gt gt 未处理的拒绝SequelizeDatabaseError 查询为空 我认识到 我使用了错误的
  • JavaScript 代码在不使用 ActiveX 的情况下截取网站屏幕截图

    我有一个用户与之交互的 JavaScript 应用程序 我需要保存当前界面的外观 裁剪出我需要的部分 或者通过指定div只拍摄我需要的部分 然后发送回服务器 显然任何外部服务都无法做到这一点 我需要一个 JavaScript 或Flash
  • 无法在前端使用 JavaScript Fetch API 将文件上传到 FastAPI 后端

    我正在尝试弄清楚如何将图像发送到我的 API 并验证生成的token那是在header的请求 到目前为止 这就是我所处的位置 app post endreProfilbilde async def endreProfilbilde requ
  • 防止文本区域出现新行

    我正在开发聊天功能 使用 Vue 并使用文本区域作为输入 以便溢出换行 并且对于编写较长消息的用户来说更具可读性 不幸的是 当用户按下 Enter 键并提交时 光标会在提交之前移动到新行 从而使用户体验感觉不佳 关于如何使用普通 Javas

随机推荐

  • [苹果开发者账号]05 换收款的银行账号

    问题场景 新公司申请的苹果开发者账号 收费APP有收入 苹果打款进入了公司银行账号 但银行反馈说 账号不能结算这笔钱 根因是 财务搞错账号业务了 解决方法 要换苹果的收款账号 提醒 涉及苹果这种境外业务 但又是可以人民币结算的 一定要和当地
  • IAR error: a declaration cannot have a label

    在使用switch时 在case 后面申请变量会出现 error a declaration cannot have a label错误 原因 Case statements are only labels This means the c
  • 【安全技术】Java 实现加密数据库连接

    一 前言 在很多项目中 数据库相关的配置文件内容都是以明文的形式展示的 这存在一定的安全隐患 在开发和维护项目时 不仅要关注项目的性能 同时也要注重其安全性 二 实现思路 我们都知道项目启动时 Spring 容器会加载配置文件并读取文件中的
  • FreeRTOS学习-软件定时器管理

    1 简介 软件定时器用于在未来的某个时间执行某个预先指定的函数 或者以一个固定的频率周期性调度该函数 这个预先指定的函数称为软件定时器回调函数 它是由软件定时器服务调用的 软件定时器由FreeRTOS的内核控制 不需要硬件的支持 不与硬件定
  • smart device industry

    公司培训 讲了一下smart device industry 不知讲得对不对 第一层 Ip Core 例如Intel MIPS ARM 第二层 芯片制造商Silicone 例如 broadcom Qualcomm BlueCore inte
  • Office2016软件安装教程

    关注公众号 免费获取资料 解压压缩文件 点击office 2013 专业增强版 64位文件夹 根据自身系统选择位数 右击setup gt 以管理员的身份运行 3 勾选接收 继续 4 选择自定义安装 5 点击浏览 选在office 安装位置
  • STM32实战项目系列教程 (一)—— 循迹小车

    前言 以往我们看到很多学习单片机知识的教程往往是从单片机内部资源出发 这样的教程原理往往晦涩难懂 初学者很难系统的学习开发单片机的项目 而本次教程是从项目出发教你学习循迹小车的制作 整个项目采用 STM32 单片机作为控制器来实现 所以在学
  • 【vue2】el-table 从接口获取数据改变了,但是页面却没有正常渲染

    方法一 在el table上面添加一个 key 属性 指定一个唯一的值 然后数据改变后 我们更新这个唯一值 这样 Vue 会自动重新渲染该组件 1 获取随机uuid 创建在uuid js文件当中 获取唯一id export function
  • 7月15日---7月21日(计划50小时,实际12小时,还有5258小时)

    本周单位事情应该不算多 没事就在家看看文挡 切忌浮躁 一颗平常心 就当学东西了 业余爱好 就按照DDRAW 软引擎 OSG引擎 自制3D引擎去走 上午PHYSX 中午DDRAW引擎 下午加入GAMEDEMO程序 晚上文挡 周六日文档 擦 最
  • 哪个进程在访问这个恶意域名???

    哪个进程在访问这个恶意域名 背景 信息安全工程师很多时候需要通过某个恶意域名来判断主机失陷情况 恶意域名特征比较明显的 比较容易通过威胁情报找到相关线索 例如fr minexmr com 通过威胁情查询 该恶意域名比较容易判断该主机感染Wa
  • 数据双向绑定

    一 什么是双向绑定 我们先从单向绑定切入单向绑定非常简单 就是把Model绑定到View 当我们用JavaScript代码更新Model时 View就会自动更新双向绑定就很容易联想到了 在单向绑定的基础上 用户更新了View Model的数
  • cocos cretor shader effect-the book of shader-4.二维矩阵

    2D Matrices 二维矩阵 前面章节 TheBookofShader开始 Shaping functions 造型函数 Color 颜色 Shapes 形状 平移 之前的章节我们学习了如何制作一些图形 而如何移动它们的技巧则是借助移动
  • 【设计模式】Chain of Responsibility 责任链式模式

    一 前言 责任链行为模式是行为模式的一种 行为模式涉及到算法和对象间职责的分配 行为模式不仅描述对象或类的模式 还描述它们之间的通信模式 行为模式分为 Template Method 模板方法 和 Interpreter 解析器行为模式 模
  • linux下安装mysql(rpm)方式安装

    前言 在linux中使用rpm安装包安装5以上版本的mysql的都可以参考这个 1 首先下载rpm安装包 要下载两个安装包一个client 一个server 有个镜像做的不错 下载地址mirrors sohu com mysql 进入后找到
  • 虚拟机centos7搭建k8s

    虚拟机centos7搭建k8s 1 踩坑大全 centos7安装的docker后 默认非root用户无法使用 所以需要创建docker组 把当前普通用户加入到组中 这里参考链接 设置docker非root用户正常使用 在给docker配置镜
  • Error creating bean with name ‘sqlSessionFactory‘ 、MySQL启动报错

    今天学习SpringSecurity的时候 选用了springboot 因为公司用的不是boot 所以 boot一直不是很熟悉 在此连接数据库的时候 遇到了一个bug Error creating bean with name sqlSes
  • UR机器人:位姿表示以及相关移动

    博主最近在做强化相关的任务 用到了UR5机械臂 所以本文主要讲述在使用过程中 对于UR机器人位姿的理解 在阅读本文之前 希望大家能够花一点时间读一下我的另一篇博文空间信息与坐标变换 本文如有错误的地方 欢迎大家指正 欢迎讨论 机座和工具 首
  • 麦科捷联合 Mellanox 加速eXtremeDB 集群性能

    2016年7月20日McObject 作为分布式数据库管理系统eXtremeDB 中集群功能的开发者 联合端对端以太网和无限宽带互联方案和服务领先供应商的Mellanox 共同宣布一个基准测试结果 该测试通过集成Mellanox的信息加速器
  • Node-RED配置

    配置文件 可通过配置文件配置Node RED 配置文件在哪 Node RED启动时 会在Node RED用户目录下寻找setting js文件 node red Windows中为系统盘 Users 当前用户 node red 若找不到 将
  • Vue3下pinia的状态管理原理和具体使用示例

    一 Pinia是什么 Pinia在Composition API的设计背景下 以Vuex下一代的构想设计了新的Vue存储状态管理库 Pinia 是一个基于 Vue 3 的状态管理库 它提供了一个可组合的 类型安全的 API 来管理 Vue