vue3前端开发-pinia小菠萝使用详细说明

news2024/11/16 21:26:58

文章目录

  • 1. 介绍
    • 1.1 Pinia介绍
    • 1.2 pinia的属性说明
  • 2. 安装
  • 3. 初步使用
  • 4. store具体使用
    • 4.1 值修改
      • 4.2.1 直接修改
      • 4.2.2 通过$patch整体修改
      • 4.2.3 通过$patch函数式
      • 4.2.4 通过$state整体修改
      • 4.2.5 通过actions修改
    • 4.2 解构store
  • 5 actions使用
  • 6. getters使用
    • 6.1 通过this获取
    • 6.2 通过state获取
    • 6.3 传参使用
  • 7.API
    • 7.1 重置state($reset)
    • 7.2 $subscribe
    • 7.3 $onActon
  • 8. 持久化插件
    • 8.1 插件安装
    • 8.2 使用
    • 8.3 局限性
      • 8.3.1 引用类型可能会失效
      • 8.3.2 基本数据类型之外的不会被序列化
    • 8.4 全局配置

1. 介绍

1.1 Pinia介绍

在这里插入图片描述
官网地址:https://pinia.vuejs.org/zh/

主要优点:
全局状态管理工具,Pinia.js有以下的特点:

  • 完整的ts支持
  • 体积小,只有1kb左右
  • 去除mutations,只有state,getter,action
  • actions支持同步与异步
  • 代码扁平化没有模块嵌套,只有store的概念,store之间可以自由使用,每个store都是独立的。
  • 无需手动添加store,store一旦创建便会自动添加
  • 支持 vue2和vue3
  • 支持插件扩展功能

什么时候可以使用?
保存全局信息的时候,例如登录的个人信息。
复杂的表单时,比如多个步骤的表单。

1.2 pinia的属性说明

defineStore方法的第一个参数:相当于为容器起一个名字。注意:这里的名字必须唯一,不能重复。
defineStore方法的第二个参数:可以简单理解为一个配置对象,里边是对容器仓库的配置。当然这种说明是以对象的形式存在。
state属性: 用来存储全局的状态的属性。
getters属性:用来监视或者说是计算状态的变化的,有缓存的功能。
actions属性:用来修改state全局状态数据的,复杂的计算逻辑可以放到这里。

2. 安装

pnpm i pinia

在main.ts中添加

import {createPinia} from 'pinia'

const store = createPinia()
app.use(store)

3. 初步使用

(1)在项目的src目录下新建store文件夹,
(2)在store文件夹里面新建store-name.ts和index.ts。

store-name用来定义枚举类型的名称作为store的唯一值。
store-name.ts

#这里定义了2个枚举名称分别为USERSYSTEM
export const enum Names{
  USER = "USER",
  SYSTEM = "SYSTEM"
}

在index.ts中,
useUserStore是通过选项式类型Store
useSystemStore是组合式类似的Store

引入仓库插件:

import {defineStore} from 'pinia'

定义仓库1,指定的唯一id,是在使用时需要
这里的useXXXXXStore 是约定俗成的命名规范,下面就是选项式定义仓库的方式。

export const useXXXXXStore = defineStore("唯一id",{
  state:()=>{},
  getters:{},
  actions:{}
}

以下两种分别介绍了选项式和组合式仓库定义的具体应用,针对唯一id,这里抽取出来作为独立的枚举类型。
也可以不用抽取,直接写,但是必须所定义的字符串是唯一的:

import {defineStore} from 'pinia'
import { Names } from './store-name'
import {ref} from "vue"

//options 选项式API
export const useUserStore = defineStore(Names.USER,{
  //data: 类似于组件中的data
  state:()=>{
    return {
      name: "张三",
      age:20
    }
  },
  //computed 修饰一些值
  getters:{
  },
  //methods 可以做同步、异步,提交state
  actions:{
  }
})

//setup store 组合式API
export const useSystemStore = defineStore(Names.SYSTEM,()=>{
  const systemInfo = ref({version:"win10"})
  function getMemory(){
    return "16G"
  }
  return {systemInfo, getMemory}
})

在vue中,分别调用2种不同store库,都可以使用:

<script setup lang='ts'>
import { useUserStore, useSystemStore } from "./store"
const user = useUserStore()
const system = useSystemStore()
</script>

<template>
  <div>
    <p>User Name:{{ user.name }}</p>
    <p>User Age: {{ user.age }}</p>
  </div>

  <div>
    <p>System Info: {{ system.systemInfo.version }}</p>
    <p>System Memory: {{ system.getMemory() }}</p>
  </div>
</template>

<style scoped></style>

页面显示如下:
在这里插入图片描述

4. store具体使用

4.1 值修改

4.2.1 直接修改

通过点击changeName和changeAge事件,可以直接修改用户的信息:
在这里插入图片描述

在点击按钮时,对应的pinia中保存的对象的值也发生改变。
在这里插入图片描述

4.2.2 通过$patch整体修改

//整体修改
const changeNameAndAge = () =>{
  user.$patch({
    name: names[randomInt(0, 4)],
    age: user.age + 1
  })
  console.log(user.name,user.age)
}

在这里插入图片描述

在这里插入图片描述

4.2.3 通过$patch函数式

user.$patch((state) => {    
    state.age = randomInt(1,100)
    state.name = checkName(state.age)
  })

在这里插入图片描述

4.2.4 通过$state整体修改

这种方式通常需要将state中的对象全部写上,否则会报错,所以一般不推荐使用。

  user.$state = {
    name: "法外狂徒张三",
    age: 30
  }

4.2.5 通过actions修改

修改src/store/index.ts中useUserStore中actions:
在这里插入图片描述

然后在vue端调用:

const changeNameAndAge4 = ()=>{
  user.setNameAndAge("张三",30)
}

4.2 解构store

直接解构Store中的对象时,是不具有响应式的,参考下图:
在这里插入图片描述

因此,为了具有响应式,需要添加pinia指定的组件storeToRefs。
第一步,先导入组件

import {storeToRefs} from "pinia"

第二步:在要解构的时候,将store对象包裹起来

const {name,age} = storeToRefs(user)

5 actions使用

模拟异步登录获取student信息

第一步,在store中定义异步方法getStudent

//定义数据类型
type Student = {
  name: string,
  grade: number
}

//模拟登陆时,2秒后获取到student的值
const loginUser = (): Promise<Student> => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve({
        name: "小明",
        grade: 3
      })
    }, 2000)
  })
}


// 在actions中使用异步获取loginUser的数据
export const useStudentStore = defineStore("student", {
  state: () => {
    return {
      student: <Student>{}
    }
  },
  getters: {},
  actions: {
    async getStudent() {
      this.student = await loginUser()
    }
  }
})

异步查询时,通常都是async和await搭配一起使用的。

第二步,在vue中使用:

//student
const studentStore = useStudentStore()
const getStudentInfo = () => {
  studentStore.getStudent()
}

studentStore可以直接调用actions里面的方法getStudent()

除此之外,在actions中,方法也可以互相调用。

// actions中方法互调
// 当name参数有值时,就更新,否则使用登陆查询的值
export const useStudentStore = defineStore("student", {
  state: () => {
    return {
      student: <Student>{}
    }
  },
  getters: {},
  actions: {
    async getStudent(name:string|null) {
      this.student = await loginUser()
      this.updateStudent(name)
    },
    updateStudent(name:string|null){
      if(name){
        this.student.name = name
      }
    }
  }
})

6. getters使用

6.1 通过this获取

    getFullName():string {
      return `${this.student.name}大学${this.student.grade}年级`
    },

6.2 通过state获取

get的每个方法中都带有一个默认的state的参数,可以直接使用state来获取值

    getFullName2(state){
      return state.student.name + "大学" + state.student.grade + "年级"
    },

6.3 传参使用

由于默认的参数是state,所以要想传参,需要返回一个带参数的方法提供调用就可以。
这里需要写成=>形式。

    getFullName3: (state)=>{
      return (firstName:string)=>  firstName +"-" + state.student.name
    }

在vue中使用时,可以传入对应的firstName变量值。

<p>student fullName3: {{ studentStore.getFullName3("张姓:") }}</p>

7.API

7.1 重置state($reset)

重置state为初始化的状态:

const resetStudentInfo = () => studentStore.$reset()

7.2 $subscribe

当state里面的值被修改时,就会触发该事件,
所以当需要监听新旧的值时,可以在此添加一些对应的逻辑判断。

studentStore.$subscribe((args,state)=>{
  console.log("args===>",args)
  console.log("state===>",state)
})

在这里插入图片描述

7.3 $onActon

本身onAction是在调用到actions中的事件时触发。

studentStore.$onAction((args)=>{
  args.after(()=>{
    console.log("after")
  })
  console.log("onAction args===>",args)
})

但是也可以做更精细的控制,就是在actions中的某个事件执行完之后再触发。
在这里插入图片描述

比如上面的1,2先分别调用了actions中的setStudent,updateStudent事件。
然后,再分别调用了args.after这个方法。
这种可以用来处理在某个actions动作发生后,添加一些处理逻辑。

8. 持久化插件

8.1 插件安装

state中的值,在页面进行刷新后,会丢失修改的数据,所以需要借助了浏览器的存储来持久化。
安装插件

pnpm i pinia-plugin-persistedstate

在main.ts中引入插件

import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import {createPinia} from 'pinia'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'  //引入

let app = createApp(App)
const pinia = createPinia()
app.use(pinia)
pinia.use(piniaPluginPersistedstate) //使用

app.mount('#app')

8.2 使用

第一种,简单使用,直接指定开启

export const useUserStore = defineStore(Names.USER, {
  state: () => {},
  getters: {},
  actions: {},
  persist: true //持久化开启
})

第二种: 指定自定义key

export const useUserStore = defineStore(Names.USER, {
  state: () => {},
  getters: {},
  actions: {},
  persist: {
    key: "my-custom-key" //自定义key
  }
})

第三种:组合式API方式的持久化,以及制定的存储类型

export const useSystemStore = defineStore(Names.SYSTEM, () => {
  const systemInfo = ref({ version: "win10" })
  function getMemory() {
    return "16G"
  }
  return { systemInfo, getMemory }
},
  {  //持久化,并自定义key
    persist: {
      key: "my-custom-key",
      storage: sessionStorage,  //sessionStorage,localStorage,
    }
  }
)

8.3 局限性

8.3.1 引用类型可能会失效

下面这种情况,b是对a的引用。因此,b和a都是指向同一个地址。

const a = {
  1: 'one',
  2: 'two',
  // ...
}
const b = a

序列化之前,a===b 结果是true

在持久化之后,由于数据将会被序列化,因此引用在刷新时将会丢失。

再次反序列化之后,a和b有着相同的内容,但是指向的是不同的对象。
a === b 结果为false

解决方法:
采取避免 a 或 b 被持久化的方法(使用 paths 选项),
并使用 afterRestore 钩子在恢复数据后重新存储它们。
这样 a 和 b 就又会有着相同的引用,两者之间的联系就恢复了。

8.3.2 基本数据类型之外的不会被序列化

解决方法:
使用 afterRestore 钩子在恢复数据后重新创建对象。
使用自定义的 serializer 来配置你想要持久化的数据类型。

8.4 全局配置

使用createPersistedState来进行全局配置。

import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import {createPinia} from 'pinia'
// import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
import { createPersistedState } from 'pinia-plugin-persistedstate'

let app = createApp(App)
const pinia = createPinia()
app.use(pinia)
// pinia.use(piniaPluginPersistedstate)

pinia.use(
  createPersistedState({
    storage: sessionStorage,
    key: id => `__persisted__${id}`,
    auto: true,
  })
)

全局配置以后,可以不需要在每个store中再额外配置,但是可以指定的store中禁用持久化。

import { defineStore } from 'pinia'
defineStore('not-persisted', {
  state: () => ({ saved: '' }),
  persist: false, //显示指定某个store不持久化
})

也可以为单独的state中变量分别指定持久化方式:

import { defineStore } from 'pinia'
defineStore('store', {
  state: () => ({
    toLocal: '',
    toSession: '',
    toNowhere: '',
  }),
  persist: [
    {
      paths: ['toLocal'],
      storage: localStorage,
    },
    {
      paths: ['toSession'],
      storage: sessionStorage,
    },
  ],
})

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

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

相关文章

nacos初步学习

Nacos初步学习 Nacos 是一个开源的服务注册和配置中心&#xff0c;它允许您注册、注销和发现服务实例&#xff0c;并提供了配置管理的功能。下面是Nacos的最基础用法&#xff1a; 1. 服务注册和发现&#xff1a; 首先&#xff0c;您需要将您的应用程序或服务注册到Nacos中。…

基于FPGA的视频接口之千兆网口(四配置)

简介 相信网络上对于FPGA驱动网口的开发板、博客、论坛数不胜数,为何博主需要重新手敲一遍呢,而不是做一个文抄君呢!因为目前博主感觉网络上描述的多为应用层上的开发,非从底层开始说明,本博主的思虑还是按照老规矩,按照硬件、底层、应用等关系,使用三~四篇文章,来详细…

MacOS安装conda

下载conda 地址https://repo.anaconda.com/miniconda/ 选择合适的安装文件下载 运行安装 执行命令安装 bash Miniconda3-latest-MacOSX-arm64.sh 设置环境变量 echo export PATH"/Users/your_user_name/miniconda3/bin:$PATH" >> ~/.zshrc source ~/.zsh…

智慧安防AI视频智能分析云平台EasyCVR加密机授权小tips

视频云存储/安防监控EasyCVR视频汇聚平台基于云边端智能协同&#xff0c;支持海量视频的轻量化接入与汇聚、转码与处理、全网智能分发、视频集中存储等。音视频流媒体视频平台EasyCVR拓展性强&#xff0c;视频能力丰富&#xff0c;具体可实现视频监控直播、视频轮播、视频录像、…

口袋参谋:批量下载优质买家秀超实用工具!

​说到买家秀&#xff0c;我相信99.9999%的卖家都不陌生&#xff0c;好看的买家秀是可以帮助店铺吸引大批消费者&#xff0c;是可以提升商品销量的。 我们先来看看买家秀的好处有哪些&#xff1f; 买家秀可以更好地获得流量 买家秀可以通过在微淘上发布&#xff0c;或者淘宝头…

接口自动化测试详解,看完不会我退出测试界

一、自动化分类 &#xff08;1&#xff09;接口自动化 python/javarequestsunittest框架来实现 python/javaRF&#xff08;RobotFramework&#xff09;框架来实现——对于编程要求不高 &#xff08;2&#xff09;Web UI功能自动化 python/javaseleniumunittestddtPO框架来实…

nginx版本号隐藏(405 not allowed解决办法)

背景 项目安全测试发现405页面暴露了nginx版本&#xff0c;其相关版本号泄露时攻击者会利用相应软件版本的当前漏洞&#xff0c;进行有效的相应攻击。所以需要我们做好版本号的隐藏。 解决办法 1.nginx版本隐藏 只需要我们在nginx.conf文件的server中添加server_tokens off&…

k8s修改集群IP--不重置集群

正常在用集群想要更换ip master 节点ip192.168.10.138 改为192.168.10.148 node1节点ip192.168.10.139 改为192.168.10.149 node2节点ip192.168.10.140 改为192.168.10.150 master 节点 1)执行脚本1233.sh 1233.sh 内容如下&#xff1a; # master 节点 export oldip1192.168.…

Outlook屏蔽Jira AI提醒

前言&#xff1a;最近不知道为什么jira上的ai小助手抽风&#xff0c;一周发个几千封邮件…导致我现在都不想在邮箱里面跟找垃圾一样找消息了。实在忍无可忍&#xff0c;决定屏蔽AI小助手&#xff0c;方法很简单&#xff0c;follow me~~ 第一步&#xff1a;双击打开电脑版Outloo…

在uniapp中为自定义组件绑定点击事件点击后没有效果

使用uniapp时&#xff0c;封装了一个Card的组件&#xff0c;为这个Card组件加上点击事件 click"handleClick"事件时&#xff0c;事件没有触发。点开微信小程序生成后的源码&#xff0c;可以看到 click的事件变成bindClick了。正确的点击事件应该是bindtap&#xff0c…

【LeetCode75】第六十八题 只出现一次的数字

目录 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 代码&#xff1a; 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 题目给我们一个数组&#xff0c;让我们返回只出现一次的数字。 那我们直接拿一个map来记录一下就好啦&#xff0c;不过题目要求只使用常…

ASEMI整流桥GBU610参数,GBU610规格

编辑-Z GBU610参数描述&#xff1a; 型号&#xff1a;GBU610 最大直流反向电压VR&#xff1a;1000V 最大工作峰值反向电压VRWM&#xff1a;700V 最大平均正向电流IF&#xff1a;6A 非重复正向浪涌电流IFSM&#xff1a;175A 操作和储存温度范围TJ ,TSTG&#xff1a;-55 t…

企业门户的必备选择,WorkPlus的定制化解决方案

在当今数字化时代&#xff0c;企业门户成为了企业内外沟通与协作的重要基础设施。WorkPlus作为领先的品牌&#xff0c;为企业提供了一站式的企业门户解决方案&#xff0c;旨在提升企业形象、改善内外部沟通与协作效率。本文将深入探讨WorkPlus如何通过定制化的设计&#xff0c;…

react父页面监听子页面关闭,进而刷新列表

如:父页面是table表格页面&#xff0c; 从父页面中打开的子页面&#xff0c;子页面中进行数据修改&#xff0c;保存后&#xff0c;父页面的table表要进行更新 部分代码: 1、父页面 fetchFinance()方法为调接口的方法: 即当子页面修改了数据保存后&#xff0c;父页面刷新tab…

视频监控系统/视频汇聚平台EasyCVR如何反向代理进行后端保活?

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安…

直播预告 | 10月12日虹科灭菌原理和灭菌工艺验证免费课程开讲,晚8点不见不散!

文章来源&#xff1a;虹科环境监测技术 点此阅读原文&#xff1a;https://mp.weixin.qq.com/s/deH8c5K9k3doJMKYWHoz4w 报名方式 复制下方链接至电脑浏览器&#xff0c;进入报名页面&#xff0c;点击“我要报名”进行报名&#xff0c;成功报名的用户开播时再次进入即可观看。 …

STC89C51基础及项目第13天:小车go、软件调速

1. 小车散件组装_推荐相同接线&#xff08;259.104&#xff09; 2. L9110s电机控制器接线&#xff08;260.105&#xff09; L9110s电机模块开发 接通VCC&#xff0c;GND 模块电源指示灯亮&#xff0c; 以下资料来源官方&#xff0c;但是不对&#xff0c;根据下节课实际调试 …

类图 UML从入门到放弃系列之二

1.劝退说明(开个玩笑) UML包含有许多小组件、修饰符以及其他小巧复杂的东西。UML的内容相当庞大&#xff0c;以至于你可以花大量的时间把自己修成一个UML语言律师&#xff0c;并能够完成所有律师能够完成的工作&#xff1a;编写出所有人都无法理解的文档。现在流行的敏捷开发倡…

MySQL 安装+启动+报错的解决方案

目录 一、安装准备 1.1 下载 1.2 版本说明 二、安装步骤 2.1 解压缩 2.2 配置环境变量 2.3 配置文件 2.4 安装 2.5 启动/停止服务 三、使用说明 3.1 用户名密码登录 3.1 设置用户名密码 四、卸载步骤 4.1 卸载服务 五、安装问题 六、启动问题 6.1 提示【服务无…

VS Code如何给Python配置虚拟环境

在python中&#xff0c;可以通过Conda创建虚拟环境&#xff0c;与PyCharm联合使用。今天&#xff0c;在VS Code 上创建虚拟环境&#xff0c;在虚拟环境中安装第三方库。 首先&#xff0c;打开一个新的空文件夹&#xff08;CRM&#xff09;。 然后&#xff0c;新建一个python文件…