Vue3状态管理库Pinia——核心概念(Store、State、Getter、Action)

news2024/11/24 20:35:16

个人简介

👀个人主页: 前端杂货铺
🙋‍♂️学习方向: 主攻前端方向,正逐渐往全干发展
📃个人状态: 研发工程师,现效力于中国工业软件事业
🚀人生格言: 积跬步至千里,积小流成江海
🥇推荐学习:🍍前端面试宝典 🍉Vue2 🍋Vue3 🍓Vue2/3项目实战 🥝Node.js🍒Three.js 🍖JS版算法
🌕个人推广:每篇文章最下方都有加入方式,旨在交流学习&资源分享,快加入进来吧

Pinia

内容参考链接
Vue3正式发布那么久了,你认识Pinia了吗?认识Pinia,搭建开发环境

文章目录

  • Pinia
    • ✨✨前言
    • ✨✨Store
      • 🎈🎈🎈State
      • 🎈🎈🎈Getters
      • 🎈🎈🎈Action
    • 🎉🎉本篇小结


✨✨前言

各位新朋友、老朋友们大家好,这里是前端杂货铺,欢迎各位的到来!!

上篇文章 我们初步认识了 Pinia,并进行了项目环境的搭建。接下来,我们从 Pinia 的核心模块着手,继续学习吧~

✨✨Store

store 就是 数据仓库,我们可以把它看成一个 只存放数据的公共组件。

🎈🎈🎈State

state 是 store 的核心,表示当前模块的状态,里面存放着我们需要使用的数据。

我们在 store 文件夹下新建 user.ts 文件,导入 defineStore(用于定义 Store)。一般 const 定义的常量都为 useXxxStore,其中 Xxx 是 defineStore 的第一个参数 xxx

之后我们在 state 中定义 age 属性。

.store/user.ts

import { defineStore } from "pinia";

/**
 * pinia 中使用 definStore 方法来定义 store
 * 第一个参数是应用程序中的 store 的唯一 id
 * 第二个参数是一个对象,store 的配置项,比如配置 store 内的数据
 */
export const useUserStore = defineStore('user', {
    // state 为 store 的核心,表示当前模块的状态
    // 为了完整类型推理,推荐使用箭头函数
    state: () => {
        return {
            age: 22
        }
    }
})

App.vue 组件中,我们导入刚才定义的 useUserStore,并定义 userStore 常量接收 useUserStore 定义模块的相关状态,之后就可以在模板中通过 userStore.xxx 的方式进行响应式获取了。

我们可以如下定义 add() 方法,使得 userStore.age += 1,在模板中的 <button></button> 中调用 add() 方法,便可以实现每点击一次按钮加一。

App.vue

<template>
  <div class="text">
    Hello pinia,I am {{ userStore.age }} years old.
  </div>
  <button @click="add">+1</button>
</template>

<script setup lang="ts">
import { useUserStore } from './store/user'

// 使用 useUserStore 并返回定义模块的相关状态以及方法
const userStore = useUserStore()

const add = () => {
  // userStore 模块里面的 state 是响应式数据
  userStore.age += 1
}

</script>

<style>
.text {
  background: orange;
}
</style>

在这里插入图片描述


🎈🎈🎈Getters

Getter 是 defineStore 参数配置项(State、Getter、Action)里面的一个属性。Getter 属性是一个对象,该对象里面是各种方法。我们可以把 Getter 看成 Vue 中的计算属性,它的作用就是返回一个新的结果。

注:与计算属性类似,Getter 也有缓存效果。(值会基于其响应式依赖被缓存。值仅会在其响应式依赖更新时才重新计算。)

在 defineStore 的第二个参数(对象)中,我们定义 getters,在里面我们可以定义一些计算方法:

  • 可以直接写箭头函数,把 state 中的值传进来,处理之后并返回
  • 可以在计算方法中调用其他计算方法,但这时要使用普通函数的写法,注:函数要加上类型限制,不然报错
  • 不同于 Vue 的计算属性,pinia 中的计算方法可以直接接收参数,注意参数写在 return 返回的函数 ()

.store/user.ts

import { defineStore } from "pinia";

/**
 * pinia 中使用 definStore 方法来定义 store
 * 第一个参数是应用程序中的 store 的唯一 id
 * 第二个参数是一个对象,store 的配置项,比如配置 store 内的数据
 */
export const useUserStore = defineStore('user', {
    // state 为 store 的核心
    state: () => {
        return {
            name: '前端杂货铺',
            age: 20
        }
    },
    getters: {
        /**
         * 箭头函数的写法,直接把 state 中的值传进来使用
         * @param state 
         * @returns 
         */
        doubleAge: (state) => state.age * 2,
        /**
         * 如果要在 Getter 中调用其他的计算属性方法,不能使用箭头函数
         * 注意:需要自己定义当前方法的返回值类型
         * @returns 
         */
        getNameAndAge():string {
            return this.name + " and " + this.doubleAge;
        },
        /**
         * 接收页面上传过来的参数,我们用年龄加上它并返回
         * @returns 
         */
        getAddAge() {
            return (num: number) => this.age + num;
        }
    },
})

我们通过 useUserStore() 创建 userStore 实例,就可以通过 X.x 的方式使用了。

下面的代码中,我们不仅仅练习了计算属性的多种用法,还使用了 ref 作对比。从页面显示的结果中我们可以发现,当点击 Getter +1 按钮时,和计算属性相关的数据会发生改变(前四个会变)。当点击 Ref +1 时,和计算属性相关的数据不会发生改变(仅最后一个会变),进一步说明了 Getter 的缓存性。

App.vue

<template>
  <div style="background: orange">
    ##state## Hello pinia,I am {{ userStore.age }} years old.
  </div>
  <div style="background: skyblue">
    ##getters箭头函数## Hello pinia,I am {{ userStore.doubleAge }} years old.
  </div>
  <div style="background: yellow">
    ##getters普通函数##,Hello pinia,I am {{ userStore.getNameAndAge }} years
    old.
  </div>
  <div style="background: yellowgreen">
    ##getters计算属性传递参数##,Hello pinia,I am
    {{ userStore.getAddAge(5) }} years old.
  </div>
  <button @click="add">##Getter## +1</button>
  <div style="background: pink">##ref响应数据##,num: {{ num }}</div>
  <button @click="numAdd">##Ref## +1</button>
</template>

<script setup lang="ts">
import { ref } from "vue";
import { useUserStore } from "./store/user";

// 使用 useUserStore 并返回定义模块的相关状态以及方法
const userStore = useUserStore();

const add = () => {
  // userStore 模块里面的 state 是响应式数据
  userStore.age += 1;
};

// ref 响应式数据
const num = ref(1);
const numAdd = () => {
  num.value += 1;
};
</script>

在这里插入图片描述


在这里插入图片描述


在这里插入图片描述


🎈🎈🎈Action

前面提到的 State 和 Getter 属性都主要是 数据层面的,并没有具体的业务逻辑代码,它们两个就和我们组件代码中的 data 数据和 computed 计算属性一样。如果我们有 业务代码 的话,最好写在 Actions 中,该属性就和我们组件代码中的 methods 相似,用来放置一些处理业务逻辑的代码。

  • state 对应 data
  • getter 对应 computed
  • action 对应 method

actions 中,我们定义修改 name 的同步方法 saveName() 和 异步方法 savaName2(),用于在 App.vue 组件中使用。

./store/user.ts

import { defineStore } from "pinia";

// 异步方法,延迟 1s
const dely = () => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(100)
        }, 1000)
    })
}

/**
 * pinia 中使用 definStore 方法来定义 store
 * 第一个参数是应用程序中的 store 的唯一 id
 * 第二个参数是一个对象,store 的配置项,比如配置 store 内的数据
 */
export const useUserStore = defineStore('user', {
    // state 为 store 的核心
    state: () => {
        return {
            name: '前端杂货铺',
            age: 20
        }
    },
    /**
     * 当前模块的相关方法
     * 存放当前模块的相关业务逻辑函数
     */
    actions: {
        /**
         * 在 pinia 中,可以直接通过 actions 修改 state
         * pinia 的 actions 里面既可以是同步也可以是异步
         * @param name 
         */
        saveName(name: string) {
            this.name = name;
        },
        /**
         * 调用异步方法,延迟 1s 更新 name 的值
         * @param name 
         */
        async saveName2(name: string) {
            // 延迟 1s 更新
            await dely();
            this.name = name;
        },
    }
})

App.vue

updateName 调用 saveName() 同步方法,点击名字立即由 前端杂货铺 => 3号杂货铺
updateName2 调用 saveName2() 异步方法,点击名字延迟 1s 后由 前端杂货铺 => 5号杂货铺

<template>
  <div style="background: orange">
    Hello pinia,My name is {{ userStore.name }} .
  </div>
  <button @click="updateName">同步修改</button>
  <button @click="updateName2">异步修改</button>
</template>

<script setup lang="ts">
import { useUserStore } from "./store/user";

// 使用 useUserStore 并返回定义模块的相关状态以及方法
const userStore = useUserStore();

const updateName = () => {
  // 直接使用 userStore 调用 actions 里定义的方法
  userStore.saveName('3号杂货铺')
}

const updateName2 = () => {
  userStore.saveName2('5号杂货铺')
}
</script>

在这里插入图片描述


在这里插入图片描述


在这里插入图片描述


🎉🎉本篇小结

本篇文章介绍了 Pinia 的核心概念。

store 是我们的数据仓库,在这里存放的数据可以在任意组件中使用,我们只需要在组件中 import 导入进来再实例化就可以使用了。

statestore 的核心,在此存放我们需要的数据。state 类似于组件中的 data。

getter 等同于 storestate 的计算值,大多数情况下,getter 仅依赖于 state,不过它们也可能会使用其他 getter,当我们使用常规的函数定义 getter 时,可以通过 this 访问到整个 store 实例。getter 类似于组件中的 computed

不同于 stategetter 针对的数据层面,action 针对的是业务逻辑层面,在 actions 中我们可以定义同步的方法,也可以定义异步的方法。actions 相当于组件中的 methods


好啦,本篇文章到这里就要和大家说再见啦,祝你这篇文章阅读愉快,你下篇文章的阅读愉快留着我下篇文章再祝!


参考资料:

  1. Pinia 官方文档
  2. Pinia 教程 【作者:千锋教育】

在这里插入图片描述


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

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

相关文章

行为型模式 - 迭代器模式

概述 定义&#xff1a; 提供一个对象来顺序访问聚合对象中的一系列数据&#xff0c;而不暴露聚合对象的内部表示。 结构 迭代器模式主要包含以下角色&#xff1a; 抽象聚合&#xff08;Aggregate&#xff09;角色&#xff1a;定义存储、添加、删除聚合元素以及创建迭代器对象…

Mind+积木编程控制小水泵给宠物喂水

前期用scratch&#xff0c;带着小朋友做了大鱼吃小鱼、桌面弹球、小学生计算器3个作品&#xff0c;小朋友收获不小。关键是小家伙感兴趣&#xff0c;做出来后给家人炫耀了一圈后&#xff0c;兴趣大增&#xff0c;嚷嚷着要做更好玩的。 最近&#xff0c;娃妈从抖音上买了个小猫喝…

JMeter 配置环境变量步骤

通过给 JMeter 配置环境变量&#xff0c;可以快捷的打开 JMeter&#xff1a; 打开终端。执行 jmeter。 配置环境变量的方法如下。 Mac 和 Linux 系统 1、在 ~/.bashrc 中加如下内容&#xff1a; export JMETER_HOMEJMeter所在目录 export PATH$JAVA_HOME/bin:$PATH:.:$JME…

pytorch安装GPU版本 (Cuda12.1)教程: Windows、Mac和Linux系统下GPU版PyTorch(CUDA 12.1)快速安装

&#x1f337;&#x1f341; 博主 libin9iOak带您 Go to New World.✨&#x1f341; &#x1f984; 个人主页——libin9iOak的博客&#x1f390; &#x1f433; 《面试题大全》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33…

【单调栈 +前缀和】AcWing 4738. 快乐子数组

原题链接 原题链接 相关算法概念介绍 前缀和&#xff08;Prefix Sum&#xff09; 前缀和是指将数组中从开头位置到当前位置的所有元素累加得到的新数组。通常&#xff0c;我们使用一个额外的数组来保存这些累加和&#xff0c;这个数组被称为前缀和数组。对于原始数组A&…

Appium+python自动化(十七)- - Monkey

1、Monkey简介 在Android的官方自动化测试领域有一只非常著名的“猴子”叫Monkey&#xff0c;这只“猴子”一旦启动&#xff0c;就会让被测的Android应用程序像猴子一样活蹦乱跳&#xff0c;到处乱跑。人们常用这只“猴子”来对被测程序进行压力测试&#xff0c;检查和评估被测…

快速排序QuickSort

目录 1.Hoare法 2.挖坑法 3.前后指针法 4.快排分治 5.关于快排 6.关于快排的优化 7.总体实现 总结&#xff1a; 快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法 其基本思想为&#xff1a;任取待排序元素序列中的某元素作为基准值&#xff0c;按照该排序码…

《5.linux驱动开发-第2部分-5.2.字符设备驱动基础》5.2.5.用开发板来调试模块

1. 首先 开发板 可以运行 Uboot 2. Ubuntu 安装好了 t f t p(启动内核zImage) 和 NFS &#xff08;挂载 根文件系统&#xff09; 3. 提前 制作好了 根文件系统&#xff08;2022年做的&#xff0c;早就忘记 怎么做了&#xff09; 4.内核 需要设置 nfs 作为根文件系统 启动…

聊聊spring-cloud的负载均衡

聊聊spring-cloud的负载均衡 1. 选择合适的负载均衡算法2. 合理设置超时时间3. 缓存服务实例列表4. 使用断路器5. 使用缓存Spring Cloud负载均衡组件对比RibbonLoadBalancerWebClient对比 总结 在微服务架构中&#xff0c;负载均衡是非常重要的一个环节&#xff0c;可以有效地提…

ES6基础知识三:对象新增了哪些扩展?

一、属性的简写 ES6中&#xff0c;当对象键名与对应值名相等的时候&#xff0c;可以进行简写 const baz {foo:foo}// 等同于 const baz {foo}方法也能够进行简写 const o {method() {return "Hello!";} };// 等同于const o {method: function() {return "…

C# List 详解四

目录 18.FindLast(Predicate) 19.FindLastIndex(Int32, Int32, Predicate) 20.FindLastIndex(Int32, Predicate) 21.FindLastIndex(Predicate) 22.ForEach(Action) 23.GetEnumerator() 24.GetHashCode() 25.GetRange(Int32, Int32) C#…

协作实现时序数据高效流转链路 | 7.20 IoTDB X RocketMQ 技术沙龙线上直播回顾

7 月 20 日&#xff0c;IoTDB X RocketMQ 技术沙龙线上直播圆满结束。工业物联网时序数据库研发商天谋科技、云原生事件流平台 Apache RocketMQ 社区的四位技术专家&#xff0c;针对实时数据接入、多样数据处理与系统的高扩展、高可靠特性的数据流转处理平台实现难点&#xff0…

计算机服务器被devos勒索病毒攻击怎么解决,数据库解密恢复方式

科学技术的发展为企业的生产运行提供了极大的便利性&#xff0c;但随之而来的网络安全也应该引起人们的重视。近期&#xff0c;我们收到很多企业的求助&#xff0c;企业的计算机服务器内的数据库被devos后缀勒索病毒攻击&#xff0c;导致企业许多工作无法正常运行。Devos后缀勒…

89、简述RabbitMQ的架构设计

简述RabbitMQ的架构设计 BrokerQueueExchangeRoutingKeyBinding信道架构设计图 Broker RabbitMQ的服务节点 Queue 队列&#xff0c;是RabbitMQ的内部对象&#xff0c;用于存储消息。RabbitMQ中消息只能存储在队列中。生产者投递消息到队列&#xff0c;消费者从队列中获取消息…

Sql Developer日期显示格式问题

sqldeveloper模式日期显示不是很美观 并且使用日期条件查询需要将月份转为中文&#xff0c;系统兼容性差 容易以前如下报错 ORA-01861: 文字与格式字符串不匹配 01861. 00000 - "literal does not match format string"-- sqldeveloper 中执行日期条件 &#xff08;…

2023杭电多校第二场1007-foreverlasting and fried-chicken

链接&#xff1a;Problem - 7293 (hdu.edu.cn) 思路&#xff1a; 枚举度大于4 和 6 且 共同连接 4个以上点 的两个点, 其度分别记为a 和 b 若a为上面的点, 那么答案为C(a-4, 2) * C(b, 4), 反之同理 如果直接搜点会tle, 此时用bitset优化, 状态压缩, 时间复杂度为O(n^3 /32) …

只需3步,使用Stable Diffusion无限生产AI数字人视频

效果演示 先看效果&#xff0c;感兴趣的可以继续读下去。 没有找到可以上传视频的地方&#xff0c;大家打开这个网盘链接观看&#xff1a;https://www.aliyundrive.com/s/CRBm5NL3xAE 基本方法 搞一张照片&#xff0c;搞一段语音&#xff0c;合成照片和语音&#xff0c;同…

APP抓包-资产获取+Frida反代理绕过和证书校验绕过

app抓包获取资产 1.打开模拟器&#xff0c;和电脑连接同一个wifi&#xff0c;让模拟器和电脑处于同一局域网&#xff0c;在模拟器配置代理。 burp开启监听 模拟器开启app&#xff0c;burp成功获取资产信息 有时候明明配置没问题&#xff0c;为什么抓不到app数据包呢&#xff1f…

Folx Pro 5 最好用的Mac磁力链接BT种子下载工具

除了迅雷&#xff0c;还有哪个支持磁力链接下载&#xff1f;Mac电脑如何下载磁力链接&#xff1f;经常有小伙伴问老宅。今天&#xff0c;老宅给大家推荐Folx Pro For Mac&#xff0c;Mac系统超好用的磁力下载工具。 Folx是一款功能强大且易于使用的Mac下载管理器&#xff0c;并…

ChatGPT开放自定义系统级别的指令,可设置偏好变成专属助理

OpenAI官方消息https://openai.com/blog/custom-instructions-for-chatgpt OpenAI为其大型语言模型接口ChatGPT引入了自定义指令&#xff0c;旨在为用户提供更加量身定制和个性化的体验&#xff0c;可以设置您的偏好&#xff0c;ChatGPT将在未来的所有对话中记住它们。 该功…