【Pinia】Pinia的概念、优势及使用方式

news2024/11/24 8:55:33

学习公司的项目,发现用到了Pinia,于是上网学习了一下,发现了一篇比较优秀的文章,于是将极少部分放到此记录学习,原文链接在末尾。

是什么

官网解释:

Pinia 是 Vue 的存储库,它允许您跨组件/页面共享状态。

从上面官网的解释不难看出,pinia和Vuex的作用是一样的,它也充当的是一个存储数据的作用,存储在pinia的数据允许我们在各个组件中使用。

相较于vuex的优点

●Vue2和Vue3都支持,这让我们同时使用Vue2和Vue3的小伙伴都能很快上手。
●pinia中只有state、getter、action,抛弃了Vuex中的Mutation,Vuex中mutation一直都不太受小伙伴们的待见,pinia直接抛弃它了,这无疑减少了我们工作量。
●pinia中action支持同步和异步
●良好的Typescript支持,毕竟我们Vue3都推荐使用TS来编写,这个时候使用pinia就非常合适了
●无需再创建各个模块嵌套了,Vuex中如果数据过多,我们通常分模块来进行管理,稍显麻烦,而pinia中每个store都是独立的,互相不影响。
●体积非常小,只有1KB左右。 ●pinia支持插件来扩展自身功能。 ●支持服务端渲染。

使用

安装

yarn add pinia
//或者使用 npm
npm install pinia

挂载

// main.ts


import { createApp } from "vue";
import App from "./App.vue";
import { createPinia } from "pinia";
const pinia = createPinia();


const app = createApp(App);
app.use(pinia);
app.mount("#app");

创建某一模块相关的store

/src/store/user.ts


import { defineStore } from 'pinia'


// 第一个参数是应用程序中 store 的唯一 id
export const useUsersStore = defineStore('users', {
  // 其它配置项
})

创建store很简单,调用pinia中的defineStore函数即可,该函数接收两个参数:
●name:一个字符串,必传项,该store的唯一id。
●options:一个对象,store的配置项,比如配置store内的数据,修改数据的方法等等。
我们可以定义任意数量的store,因为我们其实一个store就是一个函数,这也是pinia的好处之一,让我们的代码扁平化了,这和Vue3的实现思想是一样的。

使用该store

/src/App.vue

<script setup lang="ts">
import { useUsersStore } from "../src/store/user";
const store = useUsersStore();
console.log(store);
</script>

使用store很简单,直接引入我们声明的useUsersStore 方法即可,我们可以先看一下执行该方法输出的是什么:

添加state

我们需要存放的数据就放在options对象中的state属性内。
假设我们往store添加一些任务基本数据,修改user.ts代码。

/src/store/user.ts

import { defineStore } from 'pinia'


export const useUsersStore = defineStore("users", {
  state: () => {
    return {
      name: "小猪课堂",
      age: 25,
      sex: "男",
    };
  },
});

读取state

修改App.vue,通过解构赋值拿取数据,并让这几个数据显示出来。
注意:需要利用pinia的storeToRefs函数,将state中的数据变为响应式。

<template>
  <img alt="Vue logo" src="./assets/logo.png" />
  <p>姓名:{{ name }}</p>
  <p>年龄:{{ age }}</p>
  <p>性别:{{ sex }}</p>
</template>
<script setup lang="ts">
import { ref } from "vue";
import { useUsersStore } from "../src/store/user";
import { storeToRefs } from 'pinia';
const store = useUsersStore();
const { name, age, sex } = storeToRefs(store);
</script>

结果:
在这里插入图片描述

修改state

<template>
  <h1>我是child组件</h1>
  <p>姓名:{{ name }}</p>
  <p>年龄:{{ age }}</p>
  <p>性别:{{ sex }}</p>
  <button @click="changeName">更改姓名</button>
</template>
<script setup lang="ts">
import { useUsersStore } from "../src/store/user";
import { storeToRefs } from 'pinia';
const store = useUsersStore();
const { name, age, sex } = storeToRefs(store);
const changeName = () => {
  store.name = "小猪课堂";
};
</script>

重置state

有时候我们修改了state数据,想要将它还原,比如用户填写了一部分表单,突然想重置为最初始的状态。

<button @click="reset">重置store</button>
// 重置store
const reset = () => {
  store.$reset();
};

批量更改state数据

store.$patch((state) => {
  state.items.push({ name: 'shoes', quantity: 1 })
  state.hasChanged = true
})

替换整个state

store.$state = { counter: 666, name: '张三' }

添加getter

export const useUsersStore = defineStore("users", {
  state: () => {
    return {
      name: "小猪课堂",
      age: 25,
      sex: "男",
    };
  },
  getters: {
    getAddAge: (state) => {
      return state.age + 100;
    },
  },
});

使用getter

<template>
  <p>新年龄:{{ store.getAddAge }}</p></template>
<script setup lang="ts">
import { useUsersStore } from "../src/store/user";
const store = useUsersStore();
</script>

直接在标签上使用了store.gettAddAge方法,这样可以保证响应式

getter中调用其它getter

export const useUsersStore = defineStore("users", {
  state: () => {
    return {
      name: "小猪课堂",
      age: 25,
      sex: "男",
    };
  },
  getters: {
    getAddAge: (state) => {
      return state.age + 100;
    },
    getNameAndAge(): string {
      return this.name + this.getAddAge; // 调用其它getter
    },
  },
});

getter传参

export const useUsersStore = defineStore("users", {
  state: () => {
    return {
      name: "小猪课堂",
      age: 25,
      sex: "男",
    };
  },
  getters: {
    getAddAge: (state) => {
      return (num: number) => state.age + num;
    },
    getNameAndAge(): string {
      return this.name + this.getAddAge; // 调用其它getter
    },
  },
});
 <p>新年龄:{{ store.getAddAge(1100) }}</p>

添加actions

export const useUsersStore = defineStore("users", {
  state: () => {
    return {
      name: "小猪课堂",
      age: 25,
      sex: "男",
    };
  },
    actions: {
    saveName(name: string) {
      this.name = name;
    },
  },
});

使用actions

//app.vue
const saveName = () => {
  store.saveName("我是小猪");
};

汇总代码

main.ts代码:

import { createApp } from "vue";
import App from "./App.vue";
import { createPinia } from "pinia";
const pinia = createPinia();


const app = createApp(App);
app.use(pinia);
app.mount("#app");

user.ts代码:

import { defineStore } from "pinia";


// 第一个参数是应用程序中 store 的唯一 id
export const useUsersStore = defineStore("users", {
  state: () => {
    return {
      name: "小猪课堂",
      age: 25,
      sex: "男",
    };
  },
  getters: {
    getAddAge: (state) => {
      return (num: number) => state.age + num;
    },
    getNameAndAge(): string {
      return this.name + this.getAddAge; // 调用其它getter
    },
  },
  actions: {
    saveName(name: string) {
      this.name = name;
    },
  },
});

App.vue代码:

<template>
  <img alt="Vue logo" src="./assets/logo.png" />
  <p>姓名:{{ name }}</p>
  <p>年龄:{{ age }}</p>
  <p>性别:{{ sex }}</p>
  <p>新年龄:{{ store.getAddAge(1100) }}</p>
  <p>调用其它getter:{{ store.getNameAndAge }}</p>
  <button @click="changeName">更改姓名</button>
  <button @click="reset">重置store</button>
  <button @click="patchStore">批量修改数据</button>
  <button @click="saveName">调用aciton</button>


  <!-- 子组件 -->
  <child></child>
</template>
<script setup lang="ts">
import child from "./child.vue";
import { useUsersStore } from "../src/store/user";
import { storeToRefs } from "pinia";
const store = useUsersStore();
const { name, age, sex } = storeToRefs(store);
const changeName = () => {
  store.name = "张三";
  console.log(store);
};
// 重置store
const reset = () => {
  store.$reset();
};
// 批量修改数据
const patchStore = () => {
  store.$patch({
    name: "张三",
    age: 100,
    sex: "女",
  });
};
// 调用actions方法
const saveName = () => {
  store.saveName("我是小猪");
};
</script>

原文:
大菠萝!这一次彻底搞懂Pinia!(保姆级教程)

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

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

相关文章

海外媒体宣发:海外媒体发稿6种方式方法分享

科学创新在这个时代中起着了至关重要的作用。做为科谱网络写手&#xff0c;大家要不断找到新的专用工具来提高我们自己的文章内容品质和质量。在这篇文章中&#xff0c;我们将给大家分享6个通过美联社检验的发稿神器&#xff0c;帮你的科普文章如鱼得水。 1.现状分析专用工具在…

【直播预约中】 腾讯大数据 x StarRocks|构建新一代实时湖仓

随着信息时代的兴起&#xff0c;数据已成为推动业务决策和创新的核心要素&#xff1b;结构化、半结构化等多种类型的数据呈现爆炸式增长&#xff0c;如何高效处理和分析海量数据已经成为关键挑战&#xff0c;结合传统数仓与数据湖优势的湖仓一体&#xff08;Lakehouse&#xff…

25、字符缩放显示任意大小(LCD|OLED)

在常见的显示屏中无论是 ASCII 字符还是 GB2312 的字符&#xff0c;都只能显示字库中设定的字体大小&#xff0c;例如&#xff0c;我们想显示一些像素大小为 48x48 的字符&#xff0c;那我们又得制作相应的字库&#xff0c;非常麻烦。为此在野火的基础上编写了一些函数&#xf…

数据结构 第二章作业 线性表 西安石油大学

在顺序表中插入和删除一个结点需平均移动多少个结点&#xff1f;具体的移动次数取决于 哪两个因素&#xff1f; 在顺序表中插入和删除一个结点时&#xff0c;平均移动的结点数量取决于两个因素&#xff1a;插入/删除位置和当前顺序表的长度。 插入/删除位置&#xff1a;如果要…

webservice初探

使用jdk1.8完成了一个小示例&#xff0c;记录一下。springboot使用的2.7.15版本。 服务端 domain package com.example.wsserver.domain;public class Zonecode {public Zonecode(String code, String name) {this.code code;this.name name;}private String code;private…

vue-grid-layout移动卡片到页面底部时页面滚动条跟随滚动

问题描述&#xff1a;默认情况下 vue-grid-layout 移动卡片到页面底部时页面滚动条并不会跟随卡片滚动。 问题解决&#xff1a; 在 grid-item中的move事件中&#xff0c;获取到当前移动的元素&#xff0c;并使用scrollIntoView方法来实现滚动条跟随。 代码如下&#xff1a; c…

Apache 原生 Hadoop 运维命令

Hadoop 1、检查原生hadoop和压缩库是否可用 hadoop checknative2、打印hadoop环境的配置路径 hadoop classpathHDFS 1、查看hdfs文件系统的状态 hdfs dfsadmin -report2、获取安全模式的状态 hdfs dfsadmin -safemode get安全模式下只可进行读操作 3、文件系统健康检查 …

Windows 10 + Jenkins 2.4 安装插件时https 的证书问题及解决

本篇面临与解决的问题 本篇是在 Windows 10中安装Jenkins 2.414.1 &#xff0c; 在安装完成之后安装一些需要的插件&#xff0c; 可以在浏览器端安装插件的时候&#xff0c; 总是不成功&#xff0c; 控制台报以下错误&#xff1a; SEVERE h.model.UpdateCenter$DownloadJob#r…

工作中怎么去进行测试用例的编写

作为一个测试人员&#xff0c;无论是测试资深大佬还是刚入门的测试小白应该都知道&#xff0c;编写测试用例是我们测试的核心工作之一&#xff0c;往往测试用例写的标准与否&#xff0c;最能体现我们测试人员的差距&#xff0c;那么如何编写一篇优秀高质量的测试用例呢&#xf…

Postman应用——测试脚本Test Script

文章目录 Test Script脚本CollectionFolderRequest 解析响应体断言测试 测试脚本可以在Collection、Folder和Request的Pre-request script 和 Test script中编写&#xff0c;测试脚本可以检测请求响应的各个方面&#xff0c;包括正文、状态代码、头、cookie、响应时间等&#x…

Doris 2.0.1 Dockerfile制作

镜像编译 准备工作 1、创建目录 └── docker-build // 构建根目录 └── fe // FE 构建目录 ├── dockerfile …

JVM的内存分配及垃圾回收

内存分配 在了解Java的内存管理前&#xff0c;需要知道JVM中的内存分配。 栈 存储局部变量。在方法的定义中或在方法中声明的变量为局部变量&#xff1b;栈内存中的数据在该方法结束&#xff08;返回或抛出异常或方法体运行到最后&#xff09;时自动释放栈中存放的数据结构为…

Linux:haproxy部署--搭建nginx集群

Haproxy介绍 Haproxy是一个开源的高性能的反向代理或者说是负载均衡服务软件之一&#xff0c;它支持双机热备、虚拟主机、基于TCP和HTTP应用代理等功能。 其配置简单&#xff0c;而且拥有很好的对服务器节点的健康检查功能&#xff08;相当于keepalived健康检查&#xff09;&am…

区块链安全,哈希函数暴露的攻击向量与对策

区块链安全&#xff0c;哈希函数暴露的攻击向量与对策 简介 Length Extension Attack 是一种与某些特定类型的哈希函数&#xff08;如 MD5&#xff0c;SHA-1 和 SHA-2&#xff09;的特性有关的攻击。简单来说&#xff0c;这种攻击利用了一个事实&#xff0c;即知道 H(message)…

Spring Boot 各版本的支持时间

1. Spring Boot 各版本的支持时间 Spring Boot 2.7 的版本&#xff0c;支持到2023-11-18&#xff0c;之后就要停止支持了。 按照官网的数据&#xff0c;3.0 的版本也是到2023年11月就停止支持了。如果要转到SpringBoot3&#xff0c;直接从3.1开始吧。到写这篇文章时&#xff…

如何在电脑和手机之间无线传输大文件?不限文件格式、不压缩画质

AirDroid个人版支持在 Windows、Mac、Linux、安卓、iOS 之间跨平台互传文件&#xff0c;无需数据线&#xff0c;没有文件类型的限制&#xff0c;更不用担心图片或视频的画质被压缩——无损传输&#xff0c;轻松高效。 如果设备连接的是同一网络&#xff08;局域网内&#xff09…

【最优化】—— 最优化简介(一)

文章目录 前言最优化问题概括最优化问题的一般形式最优化问题的类型例子&#xff1a;稀疏优化 最优化的基本概念全局和局部最优解优化算法收敛性算法的渐进收敛速度算法的复杂度 前言 本系列文章作为最优化学习的相关笔记。参考书目&#xff1a;文再文老师的《最优化&#xff…

stm32f103步进电机S曲线加减速计算

S曲线主要实现低速扭力大&#xff0c;更快更稳 https://zhuanlan.zhihu.com/p/396648926?utm_campaign&utm_mediumsocial&utm_oi1361101006265331712&utm_psn1686906450235133952&utm_sourcezhihu 可点击上面链接查看啤酒杯的运动动画 摘自一段知乎上一段关于…

C#,数值计算——Logisticdev的计算方法与源程序

1 文本格式 using System; namespace Legalsoft.Truffer { /// <summary> /// Structure for logistic deviates. /// </summary> public class Logisticdev : Ran { private double mu { get; set; } private double sig {…

PaddlePaddle Hackathon 飞桨黑客马拉松热身赛上线!

挑战自我 拓展技能 激发创新 挑战极限 再次相遇黑客松 我们期待你的加入&#xff01; 第五期 PaddlePaddle Hackathon 飞桨黑客马拉松热身赛上线&#xff0c;本次活动是面向全球开发者的深度学习领域编程活动&#xff0c;鼓励开发者了解和参与飞桨深度学习开源项目与文心大…