状态管理Pinia使用详解(带你入门)
状态管理Pinia使用详解(带你从入门到入神)
序:
如果你之前使用过 vuex 进行状态管理的话,那么 pinia 就是一个类似的插件。它是最新一代的轻量级状态管理插件。你可以通过defineStore来简单创建一个存储管理。
与 vuex 相比,pinia 提供了一个更简单的 API,具有更少的操作,提供了 Composition-API 风格的 API,最重要的是,在与 TypeScript 一起使用时具有可靠的类型推断支持。
特点:
- 完整的 ts 的支持;
- 足够轻量,压缩后的体积只有1kb左右;
- 去除 mutations,只有 state,getters,actions;
- actions 支持同步和异步;
- 代码扁平化没有模块嵌套,只有 store 的概念,store 之间可以自由使用,每一个store都是独立的
- 无需手动添加 store,store 一旦创建便会自动添加;
- 支持Vue3 和 Vue2
pinia官网
1.安装
yarn add pinianpm install pinia
2.引入注册Vue3
import { createApp } from 'vue'
import { createPinia } from 'pinia'import App from './App.vue'onst app = createApp(App)app.use(createPinia())app.mount('#app')
3.初始化仓库Store
3.1.新建一个文件夹Store
3.2.新建文件[name].ts
3.3.定义仓库Store
3.4.我们需要知道存储是使用定义的defineStore(),并且它需要一个唯一的名称,作为第一个参数传递
新建文件store-namespace/index.ts
export const enum Names {Test = 'TEST'
}
store 引入
import { defineStore } from 'pinia'
import { Names } from './store-namespace'export const useTestStore = defineStore(Names.Test, {})
这个名称,也称为id,是必要的,Pania 使用它来将商店连接到 devtools。将返回的函数命名为*use…*是可组合项之间的约定,以使其使用习惯。
3.5.定义值
State 箭头函数 返回一个对象 在对象里面定义值
import { defineStore } from 'pinia'
import { Names } from './store-namespce'export const useTestStore = defineStore(Names.Test, {state:()=>{return {current:1}},//类似于computed 可以帮我们去修饰我们的值getters:{},//可以操作异步 和 同步提交stateactions:{}
})
4.State
4.1.State 是允许直接修改值的
例如current++
<template><div><button @click="Add">+</button><div>{{Test.current}}</div></div>
</template><script setup lang='ts'>
import {useTestStore} from './store'
const Test = useTestStore()
const Add = () => {Test.current++
}</script><style></style>
4.2.批量修改State的值
<template><div><button @click="Add">+</button><div>{{Test.current}}</div><div>{{Test.age}}</div></div>
</template><script setup lang='ts'>
import {useTestStore} from './store'
const Test = useTestStore()
const Add = () => {Test.$patch({current:200,age:300})
}</script><style></style>
4.3.批量修改函数形式
推荐使用函数形式 可以自定义修改逻辑
<template><div><button @click="Add">+</button><div>{{Test.current}}</div><div>{{Test.age}}</div></div>
</template><script setup lang='ts'>
import {useTestStore} from './store'
const Test = useTestStore()
const Add = () => {Test.$patch((state)=>{state.current++;state.age = 40})
}</script><style></style>
4.4.通过原始对象修改整个实例
$state您可以通过将store的属性设置为新对象来替换store的整个状态
缺点就是必须修改整个对象的所有属性
<template><div><button @click="Add">+</button><div>{{Test.current}}</div><div>{{Test.age}}</div></div>
</template><script setup lang='ts'>
import {useTestStore} from './store'
const Test = useTestStore()
const Add = () => {Test.$state = {current:10,age:30}
}</script><style></style>
4.5.通过actions修改
定义Actions
在actions 中直接使用this就可以指到state里面的值
import { defineStore } from 'pinia';
import { store } from '@/store';export const useModalStore = defineStore({id: 'modal', // 唯一的idstate: () => ({modals: []}),actions: {add(modal) {this.modals.push(modal)},remove(id) {let index = this.modals.findIndex(v => v.id == id)if (index > -1) {this.modals.splice(index, 1);}}},
});// 在组件setup函数外使用
export function useModalStoreWithOut() {return useModalStore(store);
}
使用方法直接在实例调用
<script setup lang='ts'>
iimport { useModalStoreWithOut } from '@/store/modules/modal.store';const modalStore = useModalStoreWithOut();modalStore.remove({ id });
modalStore.add({ modal });</script><style></style>
5.解构store
在Pinia里,是不允许直接解构是会失去响应性的
const Test = useTestStore()const { current, name } = Testconsole.log(current, name);
差异对比
修改Test current 解构完之后的数据不会变
而源数据是会变的
<template><div>origin value {{Test.current}}</div><div>pinia:{{ current }}--{{ name }}change :<button @click="change">change</button></div>
</template><script setup lang='ts'>
import { useTestStore } from './store'const Test = useTestStore()const change = () => {Test.current++
}const { current, name } = Testconsole.log(current, name);</script><style>
</style>
解决方案可以使用 storeToRefs
import { storeToRefs } from 'pinia'const Test = useTestStore()const { current, name } = storeToRefs(Test)
其原理跟toRefs 一样的给里面的数据包裹一层toref
源码 通过toRaw使store变回原始数据防止重复代理
循环store 通过 isRef isReactive 判断 如果是响应式对象直接拷贝一份给refs 对象 将其原始对象包裹toRef 使其变为响应式对象
6.Actions,getters
6.1.Actions(支持同步异步)
6.1.1.同步可直接调用
import { defineStore } from 'pinia'
import { Names } from './store-naspace'
export const useTestStore = defineStore(Names.TEST, {state: () => ({counter: 0,}),actions: {increment() {this.counter++},randomizeCounter() {this.counter = Math.round(100 * Math.random())},},
})
<template><div><button @click="Add">+</button><div>{{Test.counter}}</div> </div>
</template><script setup lang='ts'>
import {useTestStore} from './store'
const Test = useTestStore()
const Add = () => {Test.randomizeCounter()
}</script><style></style>
6.1.2.异步 可以结合async await 修饰
import { defineStore } from 'pinia'
import { Names } from './store-naspace'type Result = {name: stringisChu: boolean
}const Login = (): Promise<Result> => {return new Promise((resolve) => {setTimeout(() => {resolve({name: '小满',isChu: true})}, 3000)})
}export const useTestStore = defineStore(Names.TEST, {state: () => ({user: <Result>{},name: "123"}),actions: {async getLoginInfo() {const result = await Login()this.user = result;}},
})
<template><div><button @click="Add">test</button><div>{{Test.user}}</div> </div>
</template><script setup lang='ts'>
import {useTestStore} from './store'
const Test = useTestStore()
const Add = () => {Test.getLoginInfo()
}</script><style></style>
6.1.3.多个action互相调用getLoginInfo setName
state: () => ({user: <Result>{},name: "default"}),actions: {async getLoginInfo() {const result = await Login()this.user = result;this.setName(result.name)},setName (name:string) {this.name = name;}},
6.2.getters
6.2.1.使用箭头函数不能使用this this指向已经改变指向undefined 修改值请用state
主要作用类似于computed 数据修饰并且有缓存
getters:{newPrice:(state)=> `$${state.user.price}`},
6.2.2.普通函数形式可以使用this
getters:{newCurrent ():number {return ++this.current}},
6.2.3.getters 互相调用
getters:{newCurrent ():number | string {return ++this.current + this.newName},newName ():string {return `$-${this.name}`}},
pinia插件
pinia和 vuex 都有一个通病 页面刷新状态会丢失
我们可以写一个pinia 插件缓存他的值
const __piniaKey = '__PINIAKEY__'
//定义兜底变量type Options = {key?:string
}
//定义入参类型//将数据存在本地
const setStorage = (key: string, value: any): void => {localStorage.setItem(key, JSON.stringify(value))}//存缓存中读取
const getStorage = (key: string) => {return (localStorage.getItem(key) ? JSON.parse(localStorage.getItem(key) as string) : {})}//利用函数柯丽华接受用户入参
const piniaPlugin = (options: Options) => {//将函数返回给pinia 让pinia 调用 注入 context
return (context: PiniaPluginContext) => {const { store } = context;const data = getStorage(`${options?.key ?? __piniaKey}-${store.$id}`)store.$subscribe(() => {setStorage(`${options?.key ?? __piniaKey}-${store.$id}`, toRaw(store.$state));})//返回值覆盖pinia 原始值
return {...data}}}//初始化pinia
const pinia = createPinia()//注册pinia 插件
pinia.use(piniaPlugin({key: "pinia"}))
相关文章:
状态管理Pinia使用详解(带你入门)
状态管理Pinia使用详解(带你从入门到入神) 序: 如果你之前使用过 vuex 进行状态管理的话,那么 pinia 就是一个类似的插件。它是最新一代的轻量级状态管理插件。你可以通过defineStore来简单创建一个存储管理。 与 vuex 相比,pinia 提…...
Linux系统基础命令(一)
一、图形界面和终端界面 图形界面:是指采用图形方式显示的计算机操作用户界面。 终端界面:是指黑底白字的命令行界面。 什么是tty呢? tty:终端设备的统称。 tty一词源于Teletypes,或者teletypewriters,…...
djvu批量转换为pdf的工具和djvu阅读器(附下载链接)
简介 DjVuToy是一款美观易用、功能强大的DjVu处理工具,DjVuToy官方版功能包括图像文件转DjVu,支持PDG、BMP、GIF等格式。转换的同时可以进行OCR,生成双层DjVu。可以插入、删除、移动、旋转多页DjVu中的页面。还可以将多个DjVu文件合并成一个&…...
Linux | 分布式版本控制工具Git【版本管理 + 远程仓库克隆】
文章目录一、前言二、有关git的相关历史介绍三、Git版本管理1、感性理解 —— 大学生实验报告2、程序员与产品经理3、张三的CEO之路 —— 版本管理工具的诞生四、如何在Linux上使用Git1、创建仓库2、将仓库克隆到本地3、git三板斧① git add② git commit③ git push4、有关git…...
FFmpeg 编译和集成
背景FFmpeg 是一款知名的开源音视频处理软件,它提供了丰富而友好的接口支持开发者进行二次开发。FFmpeg 读作 “ef ef em peg” ,其中的 “FF” 指的是 “Fast Forward”,“mpeg” 则是 “Moving Picture Experts Group” (动态图…...
OOM的俩种情况---主动kill/被动kill
出现OOM, 有两种处理方式:1. 主动Kill; 2. 被动Kill 例:HBase Region Server OOM定位问题复盘 现象 在HBase资源隔离项目中,对测试集群进行压测时,发现region server会出现崩溃的情况,单机请求量从>200到~50每秒都…...
ssh远程连接ECS实例连接失败
尝试通过 SSH 远程连接服务来连接ECS云服务器实例时,收到“连接被拒”或“连接超时”的错误信息,可能的原因分析如下: 错误信息描述 1、错误消息:“ssh: connect to ecs-X-X-X-X.compute-xxxxxxxxx.com port 22: Connection tim…...
[框架设计] MVVM 的介绍,应用及优缺点
介绍 MVVM(Model-View-ViewModel)是一种架构模式,用于将应用程序分离为三个部分: Model(模型):负责处理应用程序的数据和业务逻辑。View(视图):负责呈现用户…...
4G模块DTU网关远程抄表方案(二):DL645/698协议国网电表
4G模块DTU网关远程抄表方案(二):DL645/698协议国网电表 1 DL 645协议简介 DL645协议是一种用于智能电能表的远程抄读通讯标准。制定该标准是为统一和规范多功能电能表与数据终端设备进行数据交换时的物理连接和通信链路及应用技术规范。DL645协议可用于远程监测电力传输和使用…...
认识微服务
目录 认识微服务 单体架构 分布式架构 服务架构演变 服务治理 微服务 总结 微服务技术对比 微服务结构 微服务技术对比 企业需求 SpringCloud SpringCloud和SpringBoot的版本兼容 认识微服务 单体架构 单体架构:将业务的所有功能集中在一个项目中开发&a…...
升级Android Studio Electric Eel问题汇总
1.升级以后找不到java可执行程序 问题原因:升级后,Android Studio自带的java目录不再是根目录/jre,调整为一个新目录 Studio根目录/jbr 修改方法:1)修改系统环境变量, JAVA_HOME调整为Studio下对应的java…...
令执法机构头疼的“虚拟货币犯罪”,为何链上天眼能“行”
谈到洗钱,你脑海中率先想到的可能是影视剧中利用赌场、收藏品拍卖等来实施犯罪。其实洗钱犯罪的花样不止于此,在近期热播的扫黑剧《狂飙》中,唐小龙为洗白“赌博资金、高利贷业务”,便通过“卖酒网销”的方式达成洗钱目的。 随着科…...
【unity】开发rts 3
一 出生点、阵营类型、阵营 实例栏-GameManage,默认有一个插槽 size 插槽数量 role 权限,host是主人,权限高 type 阵营类型,不选不限制,选的效果没看懂,文档原文: The Type field in Data al…...
突破老旧OA系统局限,打通五大业务管理体系,让效率“狂飙”
目录 用无代码构建上海致远信息化平台 一、支持类(行政人事、财务)体系 二、营销体系 三、供应链体系 四、质量管理体系 五、技术研发体系 下一步规划 我们公司用的第一套系统是 IBM 的系统,部署在本地服务器,这套系统用了十几年,当时 2020 年要全部迁移到LCHub低代…...
【vue2小知识】路由守卫的使用与解决RangeError: Maximum call stack size exceeded问题的报错。
🥳博 主:初映CY的前说(前端领域) 🌞个人信条:想要变成得到,中间还有做到! 🤘本文核心:当我们在路由跳转前与后我们可实现触发的操作 【前言】当我们在做类似于登录页面的时候&…...
Google Guice 5:AOP
1. AOP 1.1 实际开发中面临的问题 在实际开发中,经常需要打印一个方法的执行时间,以确定是否存在慢操作 最简单的方法,直接修改已有的方法,在finnally语句中打印耗时 Override public Optional<Table> getTable(String da…...
【同步、共享和内容协作软件】上海道宁与ownCloud让您的团队随时随地在任何设备上轻松处理数据
ownCloud是 一款开源文件同步、共享和 内容协作软件 可让团队随时随地 在任何设备上轻松处理数据 ownCloud开发并提供 用于内容协作的开源软件 使团队能够轻松地无缝 共享和处理文件 而无需考虑设备或位置 开发商介绍 ownCloud成立于2010年,是一个托管和同…...
Linux 文件、目录与磁盘格式
用户与用户组 用户:即某个文件的拥有者,可以管理自己账号下的文件,另有一个超级账号 root,可以统一管理全局,利用 su root 命令登录该账号。用户组:相当于群组,多个用户之间可以组成用户组&…...
锁屏面试题百日百刷-Hive篇(五)
锁屏面试题百日百刷,每个工作日坚持更新面试题。锁屏面试题app、小程序现已上线,官网地址:https://www.demosoftware.cn。已收录了每日更新的面试题的所有内容,还包含特色的解锁屏幕复习面试题、每日编程题目邮件推送等功能。让你…...
java多线程(七)线程等待与唤醒
一、wait()、notify()、notifyAll()等方法介绍 在Object.java中,定义了wait(), notify()和notifyAll()等接口。wait()的作用是让当前线程进入等待状态,同时,wait()也会让当前线程释放它所持有的锁。而notify()和notifyAll()的作用࿰…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...
【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)
要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况,可以通过以下几种方式模拟或触发: 1. 增加CPU负载 运行大量计算密集型任务,例如: 使用多线程循环执行复杂计算(如数学运算、加密解密等)。运行图…...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...
Python ROS2【机器人中间件框架】 简介
销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...
[大语言模型]在个人电脑上部署ollama 并进行管理,最后配置AI程序开发助手.
ollama官网: 下载 https://ollama.com/ 安装 查看可以使用的模型 https://ollama.com/search 例如 https://ollama.com/library/deepseek-r1/tags # deepseek-r1:7bollama pull deepseek-r1:7b改token数量为409622 16384 ollama命令说明 ollama serve #:…...
群晖NAS如何在虚拟机创建飞牛NAS
套件中心下载安装Virtual Machine Manager 创建虚拟机 配置虚拟机 飞牛官网下载 https://iso.liveupdate.fnnas.com/x86_64/trim/fnos-0.9.2-863.iso 群晖NAS如何在虚拟机创建飞牛NAS - 个人信息分享...
毫米波雷达基础理论(3D+4D)
3D、4D毫米波雷达基础知识及厂商选型 PreView : https://mp.weixin.qq.com/s/bQkju4r6med7I3TBGJI_bQ 1. FMCW毫米波雷达基础知识 主要参考博文: 一文入门汽车毫米波雷达基本原理 :https://mp.weixin.qq.com/s/_EN7A5lKcz2Eh8dLnjE19w 毫米波雷达基础…...
2.3 物理层设备
在这个视频中,我们要学习工作在物理层的两种网络设备,分别是中继器和集线器。首先来看中继器。在计算机网络中两个节点之间,需要通过物理传输媒体或者说物理传输介质进行连接。像同轴电缆、双绞线就是典型的传输介质,假设A节点要给…...
