vue3 pinia 状态管理(清晰明了)

news2024/12/23 0:09:45

前言

最近学习cloud项目,前端使用到 vue3 + ts 等技术,其中包括 pinia ,从一脸懵到渐渐清晰过程,在此记录一下,若有不足,希望大佬可以指出。
中文官方文档:https://pinia.web3doc.top/
在这里插入图片描述

一、什么是 Pinia

Pinia 是 Vue 的存储库,它允许跨组件/页面共享状态。实际上,pinia就是Vuex的升级版,官网也说过,为了尊重原作者,所以取名pinia,而没有取名Vuex,所以大家可以直接将pinia比作为Vue3的Vuex。

二、Pinia 和 Vuex 优缺点

Vuex 的优点:

  • 支持调试功能,如时间旅行和编辑
  • 适用于大型、高复杂度的Vue.js项目

Vuex 的缺点:

  • 从 Vue 3 开始,getter 的结果不会像计算属性那样缓存
  • Vuex 4有一些与类型安全相关的问题

pinia 的优点:

  • 完整的 TypeScript 支持: 与在 Vuex 中添加 TypeScript 相比,添加 TypeScript 更容易
  • 极其轻巧 (体积约 1KB)
  • store 的 action 被调度为常规的函数调用,而不是使用 dispatch 方法或 MapAction辅助函数这在 Vuex 中很常见
  • 支持多个store
  • 支持 Vue devtools、SSR 和 webpack 代码拆分
    pinia 的缺点:
  • 不支持时间旅行和编辑等调试功能

三、何时使用Pinia,何时使用Vuex

  • 由于 pinea 是轻量级的,体积很小,它适合于中小型应用。它也适用于低复杂度的Vue.js项目,因为一些调试功能,如时间旅行和编辑仍然不被支持
  • 将 Vuex 用于中小型 Vue.is 项目是过度的,因为它重量级的,对性能降低有很大影响。因此,Vuex 适用于大规模、高复杂度的 Vue.js 项目

四、安装

CMD命令:

npm install pinia

main.ts:

import { createPinia } from 'pinia'

app.use(createPinia())

五、核心概念

pinia 常用模版

import { defineStore } from 'pinia'

export const userStore = defineStore('userStore', {
	state: () => ({
	  // 内容
	}),
	actions: {
	  // 内容
	}
})

定义 State

在深入了解核心概念之前,我们需要知道 Store 是使用 defineStore() 定义的,并且它需要一个唯一名称,作为第一个参数传递

import { defineStore } from 'pinia'

// useStore 可以是 useUser、useCart 之类的任何东西
// 第一个参数是应用程序中 store 的唯一 id (userStore)
export const useStore = defineStore('userStore', {
  // other options...
})

State

大多数时候,state 是 store 的核心部分。 我们通常从定义应用程序的状态开始。 在 Pinia 中,状态被定义为返回初始状态的函数(类似 data)。 Pinia 在服务器端和客户端都可以工作。

案例

import { defineStore } from 'pinia'

// 唯一 ID: testStore
export const testStore = defineStore('testStore', {
    state: () => ({
        // 用户信息
		user: {
			id: '1',
			username: 'lanys',
			password: '123456'
		}
    })
})
<template>
    <div>
        Store: 账号{{user.username}},密码:{{user.password}}
    </div>
</template>

<script setup lang="ts">
  // 获取 testStore
  import { testStore } from '@/store/test';
  import { ref,reactive } from 'vue';
  const user = reactive({
	id: '',
	username: '',
	password: ''
  })
  // 获取创建的 testStore()
  const store = testStore() as any
  // 赋值
  user.id = store.id as string
  user.username = store.user.username as string
  user.password = store.user.password as string
</script>

实现效果

在这里插入图片描述

改变 store 中的值

可以调用 $patch 方法。 它允许您使用部分“state”对象同时应用多个更改:

  store.$patch({
    user: {
		id: '2',
		username: '张三',
		password: '456789'
	}
  })

改变值效果

在这里插入图片描述

Actions

Actions 相当于组件中的 methods。 它们可以使用 defineStore() 中的 actions 属性定义,并且它们非常适合定义业务逻辑:

import { defineStore } from 'pinia'

export const testStore = defineStore('testStore', {
    state: () => ({
        // 用户信息
		user: {
			username: '',
			password: ''
		}
    }),
	actions: {
	    // 设置 user
	    setUser(val: any) {
			this.user = val
		}
	}
})
<template>
    <div>
        <el-input v-model="loginForm.username"></el-input>
        <el-input v-model="loginForm.password"></el-input>
        <el-button  @click="onLogin()">提交</el-button>
        <div>
            <h3>store存储:账号:{{user.username}} ,密码: {{user.password}}</h3>
        </div>
    </div>
</template>

<script setup lang="ts">
  import { testStore } from '@/store/test';
  import { ref,reactive } from 'vue';
  // from
  const loginForm = reactive({
	username: '',
	password: ''
  })
  // user
  const user = reactive({
	username: '',
	password: ''
  })
  const store = testStore() as any
  // 点击事件
  const onLogin = () => {
    // store 设置 user
    store.setUser(loginForm)
    // 取出设置的user 并且展示
    user.username = store.user.username as string
    user.password = store.user.password as string
  }
</script>

实现效果

在这里插入图片描述
在这里插入图片描述

六、项目案例(用户登录存储token)

下面是项目中所使用的 Piain 案例,在此解析一下。

main.ts

  1. 注册 Pinia
  2. 注册 Pinia 插件(全局对象)
import { createPinia } from 'pinia'
import { registerStore } from './store'

app.use(createPinia())
// 注册 Pinia 插件(全局对象)
registerStore()

index.ts(全局对象插件)

作用:将 Store 作为静态属性,全局对象

import { userStore } from './modules/user'

const store: any = {}

export const registerStore = () => {
	store.userStore = userStore()
}

export default store

在这里插入图片描述

使用

store.userStore.accountLoginAction(loginForm) 是可以直接使用的

<script setup lang="ts">
// 这里指的是 store 目录下的全局对象index 文件
import store from '@/store'
// from 表单对象
const loginForm = reactive({
	username: constant.env.PROD ? '' : 'admin',
	password: constant.env.PROD ? '' : 'admin',
	key: '',
	captcha: ''
})
// 点击事件
const onLogin = () => {
    // 这是校验表单,可以忽略
	loginFormRef.value.validate((valid: boolean) => {
		if (!valid) {
			return false
		}

		// 用户登录
		store.userStore
		    // userStore 中的 accountLoginAction
			.accountLoginAction(loginForm)
			.then(() => {
				router.push({ path: '/home' })
			})
			.catch(() => {
				onCaptcha()
			})
	})
}
</script>

userStore

import { defineStore } from 'pinia'
// 登录的 api 接口文件
import { useAccountLoginApi, useMobileLoginApi, useLogoutApi } from '@/api/auth'
// api 接口文件
import { useUserInfoApi } from '@/api/sys/user'
// 缓存文件
import cache from '@/utils/cache'

export const userStore = defineStore('userStore', {
	state: () => ({
		// 用户信息
		user: {
			id: '',
			username: '',
			avatar: ''
		}
	}),
	actions: {
	    // 设置token
	    setToken(val: any) {
			this.token = val
			// 使用到 cache 文件
			cache.setToken(val)
		},
		// 异步账号登录
		async accountLoginAction(loginForm: any) {
		    // 登录请求,获取返回 data
			const { data } = await useAccountLoginApi(loginForm)
			// 设置token
			this.setToken(data.access_token)
		}
	}
})

cache缓存文件

从上面缓存 token cache.setToken(val)

import { SessionStorage, Storage } from '@/utils/storage'
// 设置缓存的key文件
import CacheKey from '@/utils/cache/key'

// 缓存
class Cache {
    // 获取 token
	getToken = (): string => {
		return Storage.getItem(CacheKey.TokenKey) || ''
	}
    // 设置 token
	setToken = (value: string) => {
		Storage.setItem(CacheKey.TokenKey, value)
	}
}

export default new Cache()

storage 工具

/**
 * window.localStorage 浏览器永久缓存
 * @method setItem 设置缓存
 * @method getItem 获取缓存
 * @method removeItem 移除缓存
 * @method clear 移除全部缓存
 */
export const Storage = {
	setItem(key: string, value: any) {
		if (value === undefined) {
			return
		}
		window.localStorage.setItem(key, JSON.stringify(value))
	},
	getItem(key: string) {
		let json: any = window.localStorage.getItem(key)
		return JSON.parse(json)
	},
	removeItem(key: string) {
		window.localStorage.removeItem(key)
	},
	clear() {
		window.localStorage.clear()
	}
}

/**
 * window.sessionStorage 浏览器临时缓存
 * @method setItem 设置缓存
 * @method getItem 获取缓存
 * @method removeItem 移除缓存
 * @method clear 移除全部缓存
 */
export const SessionStorage = {
	setItem(key: string, value: any) {
		if (value === undefined) {
			return
		}
		window.sessionStorage.setItem(key, JSON.stringify(value))
	},
	getItem(key: string) {
		let json: any = window.sessionStorage.getItem(key)
		return JSON.parse(json)
	},
	removeItem(key: string) {
		window.sessionStorage.removeItem(key)
	},
	clear() {
		window.sessionStorage.clear()
	}
}

在这里插入图片描述

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

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

相关文章

2022年海南省职业院校技能大赛“网络安全”比赛任务书

2022年海南省职业院校技能大赛“网络安全” 比赛任务书 一、竞赛时间 总计&#xff1a;360分钟 二、竞赛任务书内容 &#xff08;一&#xff09;拓扑图 &#xff08;二&#xff09;A模块基础设施设置/安全加固&#xff08;350分&#xff09; 一、项目和任务描述&#xff…

服务器怎么防勒索病毒

行业背景 随着金融行业信息化建设的飞速发展&#xff0c;金融行业信息化系统经过多年的发展建设&#xff0c;目前信息化程度已经达到了较高水平。信息技术在提高管理水平、促进业务创新、提升企业竞争力方面发挥着日益重要的作用。 需求分析 随着金融信息化的深入发展&#…

Linux调试器-gdb使用

目录 1. 背景 2. 开始使用 3. 理解 创建需要调试的代码 debug&&release 4 详细调试 list&#xff0f;l 行号 list&#xff0f;l 函数名 r或run break(b) info b(reak) d num disable breakpoints enable breakpoints n (next) s&#xff08;step&#xff09; breaktrac…

ConcurrentHashMap 的优化及其与HashTable, HashMap的区别

目录 1.优化一:减小锁粒度 2.优化二:只针对写操作加锁 3.优化三:CAS 4.优化四:扩容方式 HashMap是线程不安全的,HashTable是线程安全的,关键方法加锁了.我们更推荐的是ConcurrentHashMap ,更优化的线程安全哈希表 接下来我们总结一下ConcurrentHashMap 进行了哪些优化,比H…

Nessus 扫描log4J漏洞

系列文章 Nessus介绍与安装 Nessus Host Discovery Nessus 高级扫描 Nessus 扫描web服务 Nessus 扫描log4J漏洞 1.扫描环境搭建 1.centos7 安装装宝塔面板 2.面板里下载docker 3.进入centos检查docker是否生效 docker --version4.安装docker-compose Docker Compose是一个…

使用WordPress搭建知识库门户网站的优缺点

使用知识库软件进行知识管理&#xff0c;帮助企业节约成本&#xff0c;为客户提供一个自助服务平台&#xff0c;提高客户满意度&#xff0c;据调查&#xff0c;73%的客户宁愿在网上搜索答案&#xff0c;而不是给工作人员打电话或者发短信&#xff0c;搭建一个知识库可能会耗费时…

TCP如何保证可靠传输,为什么应用层还需要确认机制

TCP的可靠传输实现 以下区别&#xff1a; 1、可靠传输&#xff08;有序&#xff0c;保证对方一定接受到&#xff09; 2、流量控制 这两个功能都是依靠滑动窗口来实现的 TCP实现可靠传输依靠的有 序列号、自动重传、滑动窗口、确认应答等机制。 序列号 首先我们说下序列号&am…

文件操作相关知识

1、为什么使用文件 前面我们在实现通讯录时&#xff0c;每次运行结束后&#xff0c;我们所存储的数据都会消失。这是因为我们将数据存储在栈区、堆区等内存上&#xff0c;而内存是不具有持久性的&#xff0c;程序退出时&#xff0c;权限还给操作系统&#xff0c;这些数据就会丢…

Unity 3D PC平台发布|| Unity 3D Web 平台发布||Unity 3D Android平台发布

Unity 3D PC平台发布 PC 是最常见的游戏运行平台。 随着欧美游戏的崛起&#xff0c;PC 平台随之发生游戏登陆大潮。 在 PC 平台上发布游戏的步骤&#xff1a; 打开要发布的 Unity 3D 工程&#xff0c;执行 File → Build Settings 菜单命令。在 Platform 列表框中选择 PC&am…

Jenkins, docker-compose动态修改镜像版本升级部署

docker-compose镜像版本动态控制 提取.env文件进行配置通用环境变量 # 当前机器用户的home路径 HOST_HOME/home/guimu # 上传文件临时路径 TMP_DATA_PATH${HOST_HOME}/tempdata/ # media的home路径 MEDIA_HOME/media # 挂载的mysql的data路径 MYSQL_DATA_PATH${HOST_HOME}/my…

go 函数或者方法参数调用的过程

前言 最近做项目&#xff0c;使用go开发&#xff0c;但是在发生函数调用传参数时&#xff0c;对指针的指针的传递有难以理解的代码&#xff0c;就此分析过程。尤其是对于多重指针作为参数&#xff0c;而且对于一些内置函数的修改逻辑也需深入的理解。 1. demo package slice…

client-go源码学习(四):自定义Controller的工作原理、WorkQueue

本文基于Kubernetes v1.22.4版本进行源码学习&#xff0c;对应的client-go版本为v0.22.4 4、自定义Controller的工作原理 Controller中主要使用到Informer和WorkQueue两个核心组件 Controller可以有一个或多个Informer来跟踪某一个resource。Informer跟Kubernetes API Server保…

安装 Visual Studio Code、MinGW-w64、CMake

文章目录1.安装 Visual Studio Code1.1 下载1.2 安装2.安装 MinGW-w642.1 下载2.2 解压到合适的目录下2.3 添加到环境变量2.4 测试是否安装成功3.安装 CMake3.1 下载3.2 解压到合适的目录下3.3 添加到环境变量3.4 测试是否安装成功1.安装 Visual Studio Code 1.1 下载 Visual…

Options API

computed计算属性 1、复杂data的处理方式 我们知道&#xff0c;在模板中可以直接通过插值语法显示一些data中的数据。 但是在某些情况&#xff0c;我们可能需要对数据进行一些转化后再显示&#xff0c;或者需要将多个数据结合起来进行显示&#xff1b; 比如我们需要对多个d…

自动驾驶控制算法之车辆纵向控制(project)

本文为深蓝学院-自动驾驶控制与规划-第二章作业 目录 1 project introduction 2 思路提示 3 解决积分饱和的方法 3.1 IC 积分遇限削弱法 3.2 BC 反馈抑制抗饱和 4 ROSLGSVL联合仿真 1 project introduction 本项目希望大家根据PID控制方法实现一个巡航控制系统。我们已…

深度学习之边缘检测算法论文解读(EDTER: Edge Detection with Transformer)

引言 边缘检测是计算机视觉中最基本的问题之一&#xff0c;具有广泛的应用&#xff0c;例如图像分割[8&#xff0c;23&#xff0c;39&#xff0c;44&#xff0c;45&#xff0c;47]、对象检测[23]和视频对象分割[5&#xff0c;57&#xff0c;59]。给定输入图像&#xff0c;边缘…

webpack-dev-server:静态资源目录配置

目录 webpack-dev-server Webpack项目-配置自动打包 访问错误信息分析 简单配置静态资源访问目录 完整配置静态资源访问目录 directory属性 staticOptions属性 publicPath属性 serveIndex属性 watch属性 完整配置webpack.config.js示例 默认显示index.html内容配置 默…

fsdb DUMP的操作记录

参考链接&#xff1a; https://blog.csdn.net/ohuo666/article/details/124973939https://blog.csdn.net/ohuo666/article/details/124973939 https://blog.csdn.net/yuexiangallan/article/details/121760768https://blog.csdn.net/yuexiangallan/article/details/121760768…

基于 DolphinDB 的行情中心解决方案

随着国内量化金融的高速发展&#xff0c;行情数据所包含的微观交易结构信息越来越受到券商自营团队、资管团队以及各类基金的重视。这些交易团队迫切希望拥有一个与生产环境类似的投研仿真环境&#xff0c;提升研发的效率和质量。作为国内领先的高性能时序数据库厂商&#xff0…

【地铁上的Redis与C#】数据类型(七)--List类型

我们这篇文章开始讲解list类型。 什么是list list是一个存储空间保存多个数据&#xff0c;底层使用双向链表存储结构实现的一种Redis数据类型&#xff0c;。list类型一般用在存储多个数据&#xff0c;并需要对数据进入存储空间的顺序进行区分的情况下。list的存储方式是一个存…