状态管理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()的作用࿰…...
第13天-仓储服务(仓库管理,采购管理 ,SPU规格维护)
1.仓储服务开发配置 1.1.加入到Nacos注册中心 spring:application:name: gmall-warecloud:nacos:discovery:server-addr: 192.168.139.10:8848namespace: 36854647-e68c-409b-9233-708a2d41702c1.2.配置网关路由 spring:cloud:gateway:routes:- id: ware_routeuri: lb://gmal…...
Maven 命令行及例子
基本 mvn -v - show-version -version 显示版本信息mvn -h - help 显示帮助信息mvn -e -errors控制 maven 的日志级别,产生执行错误相关消息mvn -q - quiet 控制 maven 的日志级别,仅仅显示错误mvn -o - offline 运行 offline 模式,不联网更…...
JavaScript手写题
一、防抖 function debounce(fn, delay200) {let timeout null; // 定时器控制return function(...args) {if (timeout) { // 定时器存在,表示某个动作之前触发过了clearTimeout(timeout); // 清除定时器timeout null;} else {// 对第一次输入立即执行fn.apply…...
为什么图标的宽度总是8的倍数?
对于 Windows 上的所有图标而言,它的宽度总是8的倍数,这可不是因为人们喜欢2的幂,虽然在计算机世界,你会看到很多这样的数字,例如,1024,4096等。 在 Windows 的早期阶段,大多数显卡…...
常用的xpath
一、xpath 语法 简单看一下菜鸟教程即可 1、基本语法 XPath 使用路径表达式在 XML 文档中选取节点。节点是通过沿着路径或者 step 来选取的。 下面列出了最有用的路径表达式: 表达式描述nodename选取此节点的所有子节点。/从根节点选取(取子节点&#…...
【035】基于java的进销库存管理系统(Vue+Springboot+Mysql)前后端分离项目,附万字课设论文
1.3 系统实现的功能 本次设计任务是要设计一个超市进销存系统,通过这个系统能够满足超市进销存系统的管理及员工的超市进销存管理功能。系统的主要功能包括:首页、个人中心、员工管理、客户管理、供应商管理、承运商管理、仓库信息管理、商品类别管理、 …...
【Spark分布式内存计算框架——Spark Streaming】7. Kafka集成方式
集成方式 Spark Streaming与Kafka集成,有两套API,原因在于Kafka Consumer API有两套, 文档:http://spark.apache.org/docs/2.4.5/streaming-kafka-integration.html。 方式一:Kafka 0.8.x版本 老的Old Kafka Consum…...
如何引入elementUI
elementUI的引入完整引入按需引入完整引入 在 main.js 中写入以下内容: import Vue from ‘vue’; import ElementUI from ‘element-ui’; import ‘element-ui/lib/theme-chalk/index.css’; import App from ‘./App.vue’; Vue.use(ElementUI); new Vue({ el: ‘…...
vue3+rust个人博客建站日记4-Vditor搞定MarkDown
即然是个人博客,那么绝对不能丢给自己一个大大的输入框敷衍了事。如果真是这样,现在就可以宣布项目到此结束了。如今没人享受用输入框写博客。作为一个有追求的程序员,作品就要紧跟潮流。 后来,Markdown 的崛起逐步改变了大家的排…...
KDZD-JC软化击穿试验仪
一、概 述 KDZD-JC智能软化击穿试验仪是根据GB/T4074.6-2008和idtIEC60851-6:2004标准而设计的一种新型漆包圆线检测仪器。主要适用于固体绝缘材料(如:塑料、橡胶、层压材料、薄膜、树脂、云母、陶瓷、玻璃、绝缘漆等绝缘材料及绝缘件)在工…...
政府网站建设调研/渠道网官网
剪花布条 Time Limit : 1000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other) Total Submission(s) : 7 Accepted Submission(s) : 4 Problem Description 一块花布条,里面有些图案,另有一块直接可用的小饰条,里面也有一些…...
网站设置万事达u卡/百度官网认证价格
2019-02-14 【小记】 RO段、RW段和ZI段 --Image$$??$$Limit 含义(zz)转载于:https://www.cnblogs.com/skullboyer/p/10373972.html...
本地安装wordpress/计算机培训机构
strlen函数:求字符串的长度size_t strlen(const char *s)头文件:#include说明:求出s指向的字符串的长度(不包括null字符)。返回值:返回s指向的字符串的长度。size_t strlen(const char *s){size_t len 0;while(*s)len;return len;}strcpy和strncpy函数:…...
深圳个人网站建设/如何百度推广
2019独角兽企业重金招聘Python工程师标准>>> spring 提供一个Resource接口来统一底层资源一致的访问,而且提供了一些便利的接口 一、Resource接口 org.springframework.core.io.Resource,对InputStream进行了封装 package org.springframewor…...
做网站电脑需要配置很好吗/怎么创建一个网页
去掉 MyBatis XML 文件中 SQL 语句的背景色 效果图 修改方法 没改前效果...
网站主体证件/免费b2b平台推广
《PHP实例:php中getservbyport与getservbyname函数用法实例》要点:本文介绍了PHP实例:php中getservbyport与getservbyname函数用法实例,希望对您有用。如果有疑问,可以联系我们。代码如下:string getservbyport ( int …...