Pinia学习笔记 | 入门 - 映射辅助函数

news2024/11/25 7:12:18

文章目录

  • Pinia学习笔记
    • 简介
      • Pinia是什么
    • 代码分割机制案例
      • 1.挂载Pinia
        • Vue3
        • Vue2:安装`PiniaVuePlugin`插件
      • 2.定义store的两种方式options API 和 composition API
        • 使用options API模式定义
        • 使用composition API模式
      • 2.业务组件对store的使用
        • 创建store实例
        • 解构访问Pinia容器数据
        • 状态更新和Actions
        • getters使用
      • Pinia和VueDevtools
    • 映射辅助函数

Pinia学习笔记

参考文章1:上手 Vue 新的状态管理 Pinia,一篇文章就够了
参考文章2:
作者:南山种子外卖跑手
链接:https://juejin.cn/post/7089032094231298084
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

简介

Pinia是什么

Pinia是一个全新的Vue状态管理库,是Vuex的代替者(可以理解成Vuex5,Vuex不会再更新)。

Pinia和Vuex

VuexPinia
StateGettesMutations(同步)、Actions(异步)StateGettesActions(同步异步都支持)
Vuex4用于Vue3,Vuex3用于Vue2Vue2和Vue3都支持

Pinia的其他特点

  • 提供扁平结构,每个store都是互相独立的。所以pinia具有更好的代码分割且没有命名空间,也可以通过一个模块中导入另一个模块来隐式嵌套store。
  • Vue2 和 Vue3 都支持,除了初始化安装和SSR配置之外,两者使用上的API都是相同的
  • 支持Vue DevTools
  • 模块热更新
    • 无需重新加载页面就可以修改模块
    • 热更新的时候会保持任何现有状态
  • 支持使用插件扩展 Pinia 功能
  • 支持服务端渲染

mutation 已被弃用,初衷是带来 devtools 的集成方案

代码分割机制案例

某项目有3个store「user、job、pay」,另外有2个路由页面「首页、个人中心页」,首页用到job store,个人中心页用到了user store,分别用Pinia和Vuex对其状态管理。
在这里插入图片描述
先看Vuex的代码分割: 打包时,vuex会把3个store合并打包,当首页用到Vuex时,这个包会引入到首页一起打包,最后输出1个js chunk。这样的问题是,其实首页只需要其中1个store,但其他2个无关的store也被打包进来,造成资源浪费。

在这里插入图片描述

Pinia的代码分割: 打包时,Pinia会检查引用依赖,当首页用到job store,打包只会把用到的store和页面合并输出1个js chunk,其他2个store不耦合在其中。Pinia能做到这点,是因为它的设计就是store分离的,解决了项目的耦合问题。

1.挂载Pinia

安装pinia npm install pinia

Vue3

import { createApp } from 'vue'
import { createPinia } from 'pinia'; //引入createPinia 
import App from'./App.vue' //引入根组件

const pinia = createPinia() //创建pinia实例
const app = creatApp(App) //创建Vue应用实例

app.use(pinia)//安装pinia插件
app.mount('#app')

Vue2:安装PiniaVuePlugin插件

import { createPinia,PiniaVuePlugin } from 'pinia';

Vue.use(PiniaVuePlugin)
const pinia = createPinia() //创建pinia实例
new Vue({
  router,
  store,
  render: h => h(App),
  pinia
}).$mount('#app')

2.定义store的两种方式options API 和 composition API

defineStore()方法

  • 第一个参数是表示store的唯一名称id,Pinia 会把所有的模块都挂载到根容器上
  • 第二个参数可接受两类值:Setup 函数或 Option 对象。
    • 第二个参数是Option对象 对应options API的写法
      • state返回初始状态的函数。必须是箭头函数,箭头函数有利于TS类型推导。必须是函数的原因是防止服务端渲染时交叉请求导致数据状态污染(客户端渲染没有任何区别)
      • getters 就是用来封装计算属性,类似于组件的computed,有缓存功能
      • actions就是用来封装业务逻辑,类似与组件的methods,修改 state
    • 第二个参数是Setup函数 对应composition API的写法
      • ref()state 属性,用于存储容器store里的数据
      • computed()getters
      • functionaction,修改 state
  • 返回值是一个函数,该函数调用后返回store容器实例

Pinia会把所有的容器挂在到根容器

使用options API模式定义

import { defineStore } from 'pinia';
export const useCounterStore = defineStore('counterForOptions', {
  state: () => {
    return { count: 1 };
  },
 actions:{
        changeState(){ //通过this访问容器里的数据
            this.count++
        }
    }
  getters: {
  	//参数state是状态数据,可选参数
    doubleCount(state) {
      return state.count * 2;
    }
     doubleCount1(state):number { //也可以使用this,但是类型推导存在问题,必须手动指定返回值类型
      return this.count * 2;
    }
  }
});

使用composition API模式

import { ref, computed } from 'vue';
import { defineStore } from 'pinia';
export const useCounterStore = defineStore('counterForSetup', () => {
  const count = ref<number>(1);
  const doubleCount = computed(() => count.value * 2);
  function increment() {
    count.value++;
  }

  return { count, doubleCount, increment };
});

2.业务组件对store的使用

创建store实例

调用 defineStore()返回的函数时创建store实例,store实例是一个被reactive包装的对象

store实例示例
在这里插入图片描述

//组件内使用
<script setup>
//useCounterStore接收defineStore返回的函数
import { useCounterStore } from '@/stores/counter'
// 可以在组件中的任意位置访问 `store` 变量 ✨
const store = useCounterStore()
</script>

注意:组件外使用时,必须在函数内部

import { useAuthUserStore } from '@/stores/auth-user'

router.beforeEach((to, from, next) => {
	//因为路由器是在其被安装之后开始导航的
  // 必须再函数内部使用,为确保 pinia 实例被激活
  const authUserStore = useCounterStore()
  if (authUserStore.loggedIn) next()
  else next('/login')
})

解构访问Pinia容器数据

直接解构后的count变量会失去响应式,成为一次性数据。

//组件中的代码
<script setup lang="ts">
import {useMainStore} from '../store'
const {count} = useMainStore()
</script>

<template>
  <div>{{count }}</div>
</template>

解决办法:使用storeToRefs()方法,该方法的作用将解构出来的数据做ref响应式代理

storeToRefs()方法

  • 作用是创建一个引用方法。包含 store 的所有 state、 getter 和 plugin 添加的 state 属性,会跳过所有的 action 或非响应式 (不是 ref 或 reactive) 的属性
  • 底层使用toReftoRefs实现的一个 api 方法
<script setup lang="ts">
import {useMainStore} from '../store'
import {storeToRefs} from 'pinia'
const {count} = storeToRefs(useMainStore())
/*ObjectRefImpl
{
    "_object": {
        "count": 1
    },
    "_key": "count",
    "__v_isRef": true
}
*/
console.log(count)
console.log(count.value) //1
</script>

状态更新和Actions

store的$patch():批量更新state
- 参数可以是对象和函数(参数是state)

<script setup lang="ts">
import {useMainStore} from '../store'
import {storeToRefs} from 'pinia'
const mainStore = useMainStore()
const {count} = storeToRefs(useMainStore())
const changeCount = ()=>{
  //方式1:最简单的方式
  // mainStore.count++; 
  //方式2:如果需要多个数据,建议使用$patch,批量更新
  //mainStore.$patch({
  //  count:mainStore.count+1,
    //...数据名:修改后的值
    //涉及数组很麻烦
 // })
  
  //方式3:$patch(函数)其中函数的参数是state就是store的state,批量更新
  //mainStore.$patch(state=>{
  //  state.count++
  //})

  //方法4:逻辑比较多的时候可以封装到actions做处理,
  mainStore.changeState()
}
</script>

也可以直接从store中结构action,因为action也被绑定在store上

<script setup lang="ts">
import {useMainStore} from '../store'
const mainStore = useMainStore()
const {changeState} = store
</script>

getters使用

//虽然使用了三次,但是只会调用一次,有缓存功能
<template>
  <div>
   <div>{{mainStore.count }}</div>
   <p>
      <button @click="changeCount">修改数据</button>
   </p>
   <p>{{mainStore.doubleCount}}</p>
   <p>{{mainStore.doubleCount}}</p>
   <p>{{mainStore.doubleCount}}</p>
  </div>
</template>

Pinia和VueDevtools

在这里插入图片描述

在这里插入图片描述

映射辅助函数

  • mapStores()
  • mapState():将 state 属性映射为 只读的计算属性
  • mapWritableState()
  • mapActions()

1.不再使用 mapMutations。
2.Pinia为了兼容option api 提供的类似Vuex map 系列的映射辅助函数,不推荐使用。
3. mapGetters = mapState,mapGetters的底层实现逻辑和mapState一样

mapState():将 state 属性映射为 只读的计算属性
使用数组直接 同名映射:…mapState(store, [‘count’])
使用 对象 可映射为 新的名称:…mapState(store, { key: value, fn (state) })
使用对象时, value 值可以是 字符串,可以是 函数;
对象内部也可以直接定义 函数,接收 store 作为参数

在这里插入图片描述

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

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

相关文章

Vue学习笔记 之 Svg图标组件的实现步骤

1、安装依赖 首先需要安装svg-sprite-loader依赖&#xff0c;命令如下&#xff0c;这在在学习的过程中&#xff0c;就是因为没有下载该依赖&#xff0c;导致图标一直无法正常显示。 npm install svg-sprite-loader --save-dev --force2、配置svg图片处理规则 通过使用svg-spri…

【嵌入式Linux内核驱动】SPI子系统 | 硬件原理 | 应用编程 | 内核驱动 | 总体框架

1. 硬件原理 1.1 SPI通信协议 SPI&#xff08;Serial Peripheral Interface&#xff09;是由Motorola公司开发的一种通用数据总线 四根通信线&#xff1a;SCK&#xff08;Serial Clock&#xff09;、MOSI&#xff08;Master Output Slave Input&#xff09;、MISO&#xff08…

jmeter主要函数助手功用说明

jmeter中虽然有很多的插件&#xff0c;但是有些需要安装&#xff0c;有些具有一定的局限性。函数助手是一个快捷的工具库。下面记录一下函数助手中一些主要的函数的使用方法。 注&#xff1a;不内容中所有的实例均基于3.2记录 1、_BeanShell 表达式请求值后的值&#xff1a;可…

Hadoop之Hive安装

一、嵌入模式安装 1、下载Hive安装包 https://archive.apache.org/dist/hive/hive-1.2.1/ 2、上传至/root/export/software/ rz apache-hive-1.2.1-bin.tar.gz 3、解压 tar apache-hive-1.2.1-bin.tar.gz -C /root/export/servers/ cd /root/export/servers/apache-hive-1.2.…

openGauss学习笔记-09 openGauss 简单数据管理-创建数据库

文章目录 openGauss学习笔记-09 openGauss 简单数据管理-创建数据库9.1 语法格式9.2 参数说明9.3 示例 openGauss学习笔记-09 openGauss 简单数据管理-创建数据库 数据库安装完成后&#xff0c;默认生成名称为postgres的数据库。您需要自己创建一个新的数据库。 9.1 语法格式…

【Docker】Docker高级网络(NetWork)

【Docker】Docker高级网络(NetWork) 文章目录 【Docker】Docker高级网络(NetWork)1. 概述2. 网络2.1 网桥类型2.2 创建网络自定义桥2.3 查看所有网络2.4 查看特定网络的细节2.5 删除特定网络2.6 多个容器使用指定网络 参考文档&#xff1a;高级网络配置 Docker – 从入门到实践…

手机pdf怎么转换为图片?看看这几个转换方法

手机pdf怎么转换为图片&#xff1f;将手机图片转为PDF有很多好处。首先&#xff0c;PDF文件通常比图片文件更小&#xff0c;可以节省手机存储空间。其次&#xff0c;PDF文件可以更轻松地与他人共享&#xff0c;并且可以在不同设备和操作系统上打开。最后&#xff0c;将图片转换…

superheat | 超级简单的热图绘制解决方案!~(二)(聚类和注释图的添加~)

1写在前面 前面写了superheat的教程&#xff0c;今天写一下第二波&#xff0c;如何进行聚类以及添加注释图吧。&#x1f929; 分分钟提升你的heatmap的颜值哦&#xff01;~&#x1f970; 2用到的包 # devtools::install_github("rlbarter/superheat")library(superhe…

二叉树(中)+Leetcode每日一题——“数据结构与算法”“剑指Offer55-I. 二叉树的深度”“100.相同的树”“965.单值二叉树”

各位CSDN的uu们你们好呀&#xff0c;今天继续数据结构与算法专栏中的二叉树&#xff0c;下面&#xff0c;让我们进入二叉树的世界吧&#xff01;&#xff01;&#xff01; 二叉树&#xff08;上&#xff09;——“数据结构与算法”_认真学习的小雅兰.的博客-CSDN博客 二叉树链…

TypeScript 中对【泛型】的定义使用方式解读

目录 泛型函数多个泛型参数泛型约束泛型别名泛型接口泛型类 泛型&#xff08;Generics&#xff09;是指在定义函数、接口或类的时候&#xff0c;不预先指定具体的类型&#xff0c;而在使用的时候再指定类型的一种特性。使用泛型 可以复用类型并且让类型更加灵活 泛型实现类型参…

Pycharm安装 leetcode 插件

目录 本节演示Pycharm安装 leetcode 插件做算法题 打开设置&#xff1a; 点击插件&#xff1a; 搜索leetcode并安装&#xff1a; 点这里的 leetcode&#xff1a; 初次使用点这里&#xff1a; 这里输入账号和密码&#xff1a; 点击确定后还是点登录&#xff1a; 登…

【MySQL】SQL入门(一)

&#x1f697;MySQL学习起始站~ &#x1f6a9;本文已收录至专栏&#xff1a;数据库学习之旅 ❤️每章节附章节思维导图&#xff0c;文末附全文思维导图&#xff0c;感谢各位点赞收藏支出~ 一.引入 (1) SQL分类 SQL语句&#xff0c;根据其功能&#xff0c;主要分为四类&#x…

巧妙使用 CSS 渐变来实现波浪动画

目录 一、波浪的原理 二、曲面的绘制 三、波浪动画 四、文字波浪动画 五、总结一下 参考资料 之前看到coco[1]的这样一篇文章&#xff1a;纯 CSS 实现波浪效果&#xff01;[2]&#xff0c;非常巧妙&#xff0c;通过改变border-radius和不断旋转实现的波浪效果&#xff0c…

网络安全—全知识点解析(课程学习笔记)

概括来说&#xff0c;网络安全课程的主要内容包括&#xff1a; 安全基本知识 应用加密学 协议层安全 Windows安全&#xff08;攻击与防御&#xff09; Unix/Linux安全&#xff08;攻击与防御&#xff09; 防火墙技术 入侵监测系统 审计和日志分析 下面分别对每部分知识介绍相应…

Stable Diffusion - ControlNet 插件中扩展局部重绘 InpaintOnly + LaMa 算法与应用

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/131643131 LaMa: https://github.com/advimman/lama Paper: Resolution-robust Large Mask Inpainting with Fourier Convolutions LaMa: Large…

哇~~真的是你呀!今天是在LINUX上简单部署LAMP平台。

目录 一、概述 二、PHP安装配置 三、安装 四、启动 五、书写测试页面 六、客户端访问 七、安装论坛 一、概述 LAMP组成&#xff1a; &#xff08;1&#xff09; Linux 其他组件的平台 &#xff08;2&#xff09;Apache提供web服务 &#xff08;3&#xff09;MySQL|Ma…

004-Triple协议底层原理分析

目录 底层分析Http 2.0 底层分析 Http 2.0 为了解决Http 1.0 和 1.1 头信息无法压缩有很多比如空格、换行等无用字符请求和相应不能并行处理&#xff1a;一个Socket连接如果接受到Request 就必须要等到服务返回Response了才能继续发送另一个Request 就更新了Http的协议到2.…

SQL语法与数据库快速入门(1)

目录 数据库简介数据库分类常用数据库简介使用场景MySql 的安装与配置数据库客户端工具MySql 介绍SQL 简介DDL 数据库操作-创建DDL 数据库操作-查看DDL 数据库操作-修改DDL 数据库操作-删除DDL 数据库表操作简介DDL 数据库表操作-创建DDL 数据库表操作-查看DDL 数据库表操作-修…

国内值得去的外企之Google攻略

外企在国内非常的乖&#xff0c;基本上都是正常上下班&#xff0c;更有甚者&#xff0c;上班不到点不进门&#xff0c;下班一到点就跑路&#xff0c;中途还能去楼下咖啡店喝咖啡。 年假多、生活工作平衡、待遇还不错&#xff0c;下班以后同事之间几乎再无联系&#xff0c;如果…

解决matplotlib子图重叠问题

代码修改前&#xff1a; import matplotlib.pyplot as plt import seaborn as snsdef on_resize(event):print(当前画布大小为&#xff1a;{}x{}.format(event.width, event.height))if __name__ __main__:x list(range(1, 6))y1 [i ** 2 for i in x]y2 [i ** 3 for i in …