Vue3中 状态管理器 ( Pinia ) 详解及使用

传送门: Vue中 状态管理器(vuex)详解及应用场景
传送门:Pinia 中文文档

注意:本文项目使用脚手架为 Vite;

1. 前言

Pinia 对比 Vuex

  • Pinia 同时支持 Vue2 以及 Vue3 ,这让同时使用两个版本的小伙伴更容易上手;
  • Pinia 中只存在 State,getter,action,剔除掉了 Vuex 中的 Mutation 及 Module;
  • Pinia 中的 action 可同时支持同步任务、异步任务;
  • 更友好的支持了 TypeScript ,无需创建自定义复杂包装器来支持 TypeScript,所有内容都是类型化的,并且 API 的设计方式尽可能利用 TS 类型推断;
  • Pinia 在修改状态的时候不需要通过其他 api,如:vuex 需通过 commit,dispatch 来修改,所以在语法上比 vuex 更容易理解和使用灵活;
  • 由于去除掉了 Module ,无需再创建各个模块嵌套了。Vuex 中,如果数据过多,通常会通过划分模块来进行管理,而 Pinia 中,每个 Store 都是独立的,互不影响;
  • 支持服务端渲染;

2. 安装及引入

yarn add pinia
// 或者使用 npm
npm install pinia

安装完 Pinia 包之后,需要在 main.js 文件中导入 createPinia 函数并将 Pinia 插件与 Vue 应用程序绑定:

import { createApp } from 'vue';
import App from './App.vue';
// 引入 createPinia 函数
import { createPinia } from 'pinia';const app = createApp(App)
// 使用 createPinia() 来创建 Pinia(根存储),并应用到整个应用中
app.use(createPinia());
app.mount('#app');

使用 createPinia() 函数创建并初始化 Pinia 插件实例,将其与 Vue 应用程序绑定使用 app.use(pinia)。至此,我们就可以使用Pinia 来管理 Vue 应用程序的状态了。

最后,在 src 文件下创建一个 store 文件夹,并添加 store.js 文件。

3. Pinia 的使用

Store

Store 是使用 defineStore() 定义的,并且它需要一个唯一名称,作为第一个参数传递。这个名字 ,也被用作 id 是必须传入的, Pinia 将用它来连接 store 和 devtools。将返回的函数命名为 use… 是跨可组合项的约定,以使其符合使用习惯。

State

State 是 store 中存储数据的地方。通过定义 State,可以在 store 的任何位置访问和修改数据。

// store/store.js
import { defineStore } from 'pinia';export const useMainStore = defineStore('main',{state: () => {return {count:0}}
})
// views/home.vue
<template><div class="count">state:{{mainStore.count}}</div><div class="btnWrap"><button  @click="resetStore">重 置</button></div>
</template><script setup>import {useMainStore} from '@/store/store.js';const mainStore = useMainStore();console.log(mainStore.count) // 0const resetStore = () => {mainStore.$reset()}
</script>

效果:

在这里插入图片描述

Getters

Getter 用来获取从 state 派生的数据,类似于 Vue 组件中的 computed 计算属性。可通过 defineStore() 中的 getters 属性来定义它们。推荐使用箭头函数,并且它将接收 state 作为第一个参数:

export const useStore = defineStore('main', {state: () => ({count: 0,}),getters: {doubleCount: (state) => state.count * 2,},
})
Actions

Action 相当于组件中的方法。它可以通过 defineStore() 中的 actions 属性来定义;Action 是一种将异步操作封装在 store 中的方式,它是一个可被调用的函数,也可接收参数并修改 store 中的状态。

import { defineStore } from 'pinia'export const myStore = defineStore('myStore',{ state: () => ({message: 'Hello',}),actions: {async fetchMessage() {const res = await fetch('http://127.0.0.1:5173/message')this.message = res.message},},
})

4. 示例完整代码

4.1 选项式写法
// store/store.js
import { defineStore } from 'pinia';
import axios from 'axios';export const useMainStore = defineStore('main',{state: () => {return {count:0,count2:0,list:[],}},getters:{doubleCount(){return this.count*2;}},actions:{add(){this.count++;},update(val){this.count = val.value;},add2(){this.count2++;},// 异步async getList(){const res = await axios.get('https://api.oioweb.cn/api/common/history');if(res.data.code == 200){this.list = res.data.result || [];}},}
})

在组件中使用

<template><div class="count">state:{{mainStore.count}}</div><div class="count">getters:{{mainStore.doubleCount}}</div><div class="btnWrap"><button @click="resetStore">重 置</button><button @click="addCount">增 加</button><button @click="updateCount">更新至100</button></div><hr/><div class="count">state:{{count2}}</div><div class="btnWrap"><button @click="add2">增 加</button></div><hr/><h3>历史上的今天</h3><ul class="list"><li v-for="(item,index) in mainStore.list":key="index">{{item.year}}年 - {{item.title}}</li></ul>
</template><script setup>import {useMainStore} from '@/store/store.js';import {onMounted,ref} from 'vue';import {storeToRefs} from 'pinia';const mainStore = useMainStore();const {count2} = storeToRefs(mainStore);const {add2} = mainStore;console.log(mainStore)const number = ref(100);const resetStore = () => {mainStore.$reset();}const addCount = () => {mainStore.add();};const updateCount = () => {mainStore.update(number);}onMounted(() => {mainStore.getList();})
</script>

效果:
分别触发 add2 两次,addCount、getList 一次后的效果
在这里插入图片描述

4.2 组合式写法

在组合式 API 中:

  • ref() 相当于 state 属性;
  • computed() 相当于 getters;
  • function() 相当于 actions;
// store/count.js
import { defineStore } from 'pinia';
import {computed, ref} from 'vue';
import axios from 'axios';// 第一个参数是应用中 Store 的唯一 ID
export const useCountStore = defineStore('count',() => {// stateconst count = ref(0);const count2 = ref(0);const list = ref([]);// getter const doubleCount = computed(() => {return count.value*2})// 同步action const add = () => {count.value++;}const update = (val) =>{count.value = val.value;}const add2 = () => {count2.value++;}// 异步action const getList = async () => {const res = await axios.get('https://api.oioweb.cn/api/common/history');if(res.data.code == 200){list.value = res.data.result || [];}}return{count,count2,doubleCount,list,add,update,add2,getList,}
})

在组件中使用

<template><div class="count">state:{{countStore.count}}</div><div class="count">getters:{{countStore.doubleCount}}</div><div class="btnWrap"><button @click="resetStore">重 置</button><button @click="addCount">增 加</button><button @click="updateCount">更新至100</button></div><hr/><div class="count">state:{{count2}}</div><div class="btnWrap"><button @click="add2">增 加</button></div><hr/><h3>历史上的今天</h3><ul class="list"><li v-for="(item,index) in countStore.list":key="index">{{item.year}}年 - {{item.title}}</li></ul>
</template><script setup>import {useCountStore} from '@/store/count.js';import {onMounted,ref} from 'vue';import {storeToRefs} from 'pinia';const countStore = useCountStore();const {count2} = storeToRefs(countStore);const {add2} = countStore;console.log(countStore)const number = ref(100);const resetStore = () => {countStore.$reset();}const addCount = () => {countStore.add();};const updateCount = () => {countStore.update(number);}onMounted(() => {countStore.getList();})
</script>

效果:
分别触发 add2 两次,addCount、getList 一次后的效果
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/690016.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

现货白银投资热度推升因子

白银作为一种贵金属&#xff0c;其投资价值会受到多种因素的影响。在一些特殊的情况下&#xff0c;现货白银作为具有高杠杆的白银替代投资方式&#xff0c;会成为热门的投资工具&#xff0c;大受市场的追捧&#xff0c;本文将为大家介绍一下相关情况。 通常当全球的经济面临不确…

【Linux】进程间通信——共享内存

文章目录 共享内存的概要创建共享内存shmget()参数keyshmget()参数sizeshmget()参数shmflg 删除共享内存挂载共享内存去关联 共享内存的概要 共享内存允许两个不相关的进程访问同一个逻辑内存。共享内存是在两个正在运行的进程之间传递数据的一种非常有效的方式。不同进程之间…

【ArcGIS Pro二次开发】(81):玩个花活_控规指标块生成

一、要实现的效果 废话不多说&#xff0c;这次要实现的是类似控规指标块的标注&#xff1a; 这里只是示例&#xff0c;用了5个格子&#xff0c;做成9个格子也是可以的。 实现这个效果最关键的是要用到Pro中的复合标注。 关于复合标注的用法可以搜一下帮助里的【使用复合注释…

【区块链技术开发语言】在ubuntu18 系统环境下命令操作安装GO语言开发环境

要在Ubuntu 18系统上安装GO语言开发环境,您可以按照以下步骤进行: 打开终端(Ctrl + Alt + T)。 使用以下命令下载GO语言安装包: 或者手动打开链接下载: wget https://golang.org/dl/go1.17.5.linux-amd64.tar.gz确保替换链接中的版本号为最新版本。 解压下载的安装包…

yolov8源码解读Detect层

yolov8源码解读Detect层 Detect层解读网络各层解读及detect层后的处理 关于网络的backbone,head&#xff0c;以及detect层后处理&#xff0c;可以参考文章结尾博主的文章。 Detect层解读 先贴一下全部代码,下面一一解读。 class Detect(nn.Module):"""YOLOv8 …

【EndNote20】Endnote20和word的一些操作

文章目录 前言一、如何导入参考文献到EndNote201.1.在谷歌学术或知网上下载文献1.2.将下载好的文件导入EndNote20(可批量导入)1.3.书籍如何导入 二、Word中加入参考文献 前言 做毕设时学习了EndNote20的一些使用方法&#xff0c;并在此慢慢做汇总。 一、如何导入参考文献到End…

【python】python入门之输入与进入交互模式的方法

目录 一次性输入&#xff08;进入交互模式&#xff09;&#xff1a; 输入函数&#xff1a; 一次性输入&#xff08;进入交互模式&#xff09;&#xff1a; 交互模式介绍&#xff1a;写一行读一行&#xff0c;不用print也可以显示出来 &#xff08;当进行某些一次性计算或者纠错…

在石家庄有哪家券商证券公司可以免费开量化软件Ptrade、QMT

在石家庄有少数证券公司可以免费开量化软件QMT、Ptrade&#xff0c;如国金证券、广发证券等&#xff0c;之前要100万才可开通&#xff0c;现在只需满足资金50万的条件即可免费办理使用&#xff0c;详情找客户经理孙经理咨询。 证券佣金低价标准是“成本价”&#xff0c;默认佣金…

多线程——

目录 一、为什么要有多线程&#xff1f; 1、线程与进程 2、多线程的应用场景 3、小结​编辑 二、多线程中的两个概念&#xff08;并发和并行&#xff09; 1、并发 2、并行 3、小结 三、多线程的三种实现方式 1、继承Thread类的方式进行实现 2、实现Runnable接口的方…

为什么有的代理IP速度比较慢?

“为什么有的IP代理速度比较慢&#xff1f;”随着数字化时代的不断发展&#xff0c;代理服务成为了许多网络操作的关键环节。然而&#xff0c;有时我们可能会遇到IP代理速度慢的问题&#xff0c;这可能会对我们的网络操作产生影响。让我们一起揭开这个谜团&#xff0c;探寻其中…

EMQX Enterprise 5.4 发布:OpenTelemetry 分布式追踪、OCPP 网关、Confluent 集成支持

EMQX Enterprise 5.4.0 版本已正式发布&#xff01; 新版本提供 OpenTelemetry 分布式追踪与日志集成功能&#xff0c;新增了开放充电协议 OCPP 协议接入能力&#xff0c;并为数据集成添加了 Confluent 支持。此外&#xff0c;新版本还进行了多项改进以及 BUG 修复&#xff0c…

AI提示工程实战:从零开始利用提示工程学习应用大语言模型【文末送书-19】

文章目录 背景什么是提示工程&#xff1f;从零开始&#xff1a;准备工作设计提示调用大语言模型 实际应用示例文字创作助手代码生成持续优化与迭代数据隐私与安全性可解释性与透明度总结 AI提示工程实战&#xff1a;从零开始利用提示工程学习应用大语言模型【文末送书-19】⛳粉…

SpringMVC 的参数绑定之list集合、Map

标签中name属性的值就是pojo类的属性名 参数绑定4 list [对象] <form action"teaupd.do" method"post"> <c:forEach items"${list}" var"tea" varStatus "status"> 教师编号&#xff1a;<input…

希尔排序算法

目录 ShellSort希尔排序 整体思路 图解分析 【1】预排序 单组排序 多组并排 【2】直接插入排序 关于gap取值 总代码实现 时间复杂度 ShellSort希尔排序 希尔排序法又称缩小增量法。 希尔排序法的基本思想是&#xff1a;先选定一个整数&#xff0c;把待排序文件中所有…

Vue3快速上手(七) ref和reactive对比

一、ref和reactive对比 表格形式更加直观吧&#xff1a; 项目refreactive是否支持基本类型支持不支持是否支持对象类型支持支持对象类型是否支持属性直接赋值不支持&#xff0c;需要.value支持是否支持直接重新分配对象支持&#xff0c;因为操作的.value不支持&#xff0c;需…

120 Linux C++ 通讯架构实战 nginx整体结构,nginx进程模型,nginx调整worker进程数量,nginx重载配置文件,热升级,关闭

一 nginx整体结构 1.1 master进程和worker进程概览&#xff08;父子关系&#xff09; 启动nginx&#xff0c;看到了master进程和 worker 进程。 ps -ef | grep nginx 第一列&#xff1a;进程所属的用户id 第二列&#xff1a;进程ID&#xff0c;也叫做PID&#xff0c;用来唯…

@arco.design Modal renderContent 增加样式

方式一&#xff1a;通过 h 函数 import { h } from vueMessage.error({content: () > {return h(div, {}, [手机号 , h(span, { style: { color: red } }, staffPhone), 已存在])}, })方式二&#xff1a;通过 jsx 方式 注意&#xff1a;lang 需要改为 jsx 或者 tsx <s…

OSQP文档学习

OSQP官方文档 1 QSQP简介 OSQP求解形式为的凸二次规划&#xff1a; x ∈ R n x∈R^n x∈Rn&#xff1a;优化变量 P ∈ S n P∈S^n_ P∈Sn​&#xff1a;半正定矩阵 特征 &#xff08;1&#xff09;高效&#xff1a;使用了一种自定义的基于ADMM的一阶方法&#xff0c;只需…

关于Sora的一些紧迫问题...

OpenAI Sora 概述 OpenAI最新的创新&#xff0c;Sora&#xff0c;在人工智能领域开辟了新的天地。Sora是一个文本到视频的扩散模型&#xff0c;可以将文本描述转化为逼真的视频内容。它解决了一个重大的技术挑战&#xff0c;即在视频中保持主体的一致性&#xff0c;即使它们暂…

Java 线程池的基本操作

Java 线程池的基本操作 package com.zhong.thread.threadpool;import java.util.concurrent.*;/*** ClassName : ThreadPool* Description : 线程池的基本操作* Author : zhx* Date: 2024-02-19 18:03*/ public class ThreadPool {public static void main(String[] args) {// …