全新的 Vue3 状态管理工具:Pinia

大家好,我是若川。最近组织了源码共读活动,感兴趣的可以点此加我微信 ruochuan12 参与,每周大家一起学习200行左右的源码,共同进步。同时极力推荐订阅我写的《学习源码整体架构系列》 包含20余篇源码文章。


Vue3 发布已经有一段时间了,它采用了新的响应式系统,而且构建了一套全新的 Composition API。Vue 的周边生态都在加紧适配这套新的系统,官方的状态管理库 Vuex 也在适配中,为此官方提出了一个 Vuex 5 的全新提案。

5acffb692717b025516220643d4fe65b.png
  • 支持两种语法创建 Store:Options ApiComposition Api

  • 删除 mutations,只支持 stategettersactions

  • 模块化的设计,能很好支持代码分割;

  • 没有嵌套的模块,只有 Store 的概念;

  • 完整的 TypeScript 支持;

在这个提案下方,有个评论很有意思。简单翻译一下:

d6e4a6683336132e51f5acbdd1f32c68.png

好巧不巧,Vuex5 的提案,与 Pinia 实现的功能不能说毫无关系,只能说一模一样,今天的文章就来给大家介绍一下这个菠萝。

安装

在现有项目中,用过如下命令进行 Pinia 模块的安装。

# yarn
yarn add pinia@next
# npm
npm i pinia@next

安装完成后,需要在 Vue3 项目的入口文件中,进行导入安装。

// main.js
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'// 实例化 Vue
const app = createApp(App)
// 安装 Pinia
app.use(createPinia())
// 挂载在真实 DOM
app.mount('#app')

上手

要使用 Pinia 的话,只需要定义一个 store,然后在用到该数据的地方进行导入。

定义 Store

import { defineStore } from "pinia"// 对外部暴露一个 use 方法,该方法会导出我们定义的 state
const useCounterStore = defineStore({// 每个 store 的 id 必须唯一id: 'counter',// state 表示数据源state: () => ({count: 0}),// getters 类似于 computed,可对 state 的值进行二次计算getters: {double () {// getter 中的 this 指向👉 statereturn this.count * 2},// 如果使用箭头函数会导致 this 指向有问题// 可以在函数的第一个参数中拿到 statedouble: (state) => {return state.count * 2}},// actions 用来修改 stateactions: {increment() {// action 中的 this 指向👉 statethis.count++},}
})export default useCounterStore

除了使用上述类似 vuex 的方式来构建 state,还可以使用 function 的形式来创建 store,有点类似于 Vue3 中的 setup()

import { ref, computed } from "vue"
import { defineStore } from "pinia"// 对外部暴露一个 use 方法,该方法会导出我们定义的 state
const useCounterStore = defineStore('counter', function () {const count = ref(0)const double = computed(() => count.value * 2)function increment() {count.value++}return {count, double, increment}
})export default useCounterStore

使用 Store

前面也介绍过,Pinia 提供了两种方式来使用 store,Options ApiComposition Api 中都完美支持。

Options Api

Options Api 中,可直接使用官方提供的 mapActionsmapState 方法,导出 store 中的 state、getter、action,其用法与 Vuex 基本一致,很容易上手。

import { mapActions, mapState } from 'pinia'
import { useCounterStore } from '../model/counter'export default {name: 'HelloWorld',computed: {...mapState(useCounterStore, ['count', 'double'])},methods: {...mapActions(useCounterStore, ['increment'])}
}

Composition Api

Composition Api 中,不管是 state 还是 getter 都需要通过 computed 方法来监听变化,这和 Options Api 中,需要放到 computed 对象中的道理一样。另外, Options Api  中拿到的 state 值是可以直接进行修改操作的,当然还是建议写一个 action 来操作 state 值,方便后期维护。

// Composition Api
import { computed } from 'vue'
import { useCounterStore } from '../stores/counter'
export default {name: 'HelloWorld',setup() {const counter = useCounterStore()return {// state 和 getter 都需要在使用 computed,这和 Options Api 一样count: computed(() => counter.count),double: computed(() => counter.double),increment: () => { counter.count++ }, // 可以直接修改 state 的值increment: counter.increment, // 可以引用 store 中定义的 action}}
}

类型提示

在 Vuex 中,TypeScript 的类型提示做得不是很好,在进行类型推导时,只能找到它的 state。特别是写代码的过程中,代码提示就很不智能。

0a6f2d374f075f4b8819f8a9581d054a.png

而 pinia,就能推导出定义的所有 state、getter、action,这样在写代码的时候,就会方便很多。

1bd0de09bbd092b04e951b2d88867b23.png988c7b6128257f139afcaf70f3a83664.png

主要是 pinia 通过 TypeScript 进行了十分友好的类型定义,感兴趣的可以看看 pinia 的类型定义文件(pinia.d.ts):

cefbc35033cea58fc9f21b5ae6199999.png

代码分割

由于使用了模块化设计,所有的 store 都能够单独引入,而不是像 vuex 一样,通过 modules 的方式,将所有的 module 挂载到一个 store 上。

假设,我们当前通过 Vuex 创建了一个 Store,这个 Store 下有两个 module,分别是用户模块(User)和商品模块(Goods)。即使当前首页只使用到了用户信息,但是整个 Store 都会被打包到首页的 js chunk 中。

3995d8a73992542840fd9dd97569517e.pngd95ad7e944f9749b72346724c6e0781c.png

如果我们使用 pinia,我们会使用 defineStore 定义两个 完全是分离状态的 store,两个页面在引入时,也互不影响。最后打包的时候,首页的 js chunk 和商品页的 js chunk 会分别打包对应的 store。

ebf8e1b10992786e626fe239859c29eb.png

Pinia 的介绍到这里就告一段落了,如果现在有新项目要使用 Vue3 进行开发,推荐无脑使用 Pinia,更加简洁,而且大小仅 1KB。

- END -

61c78928b666ba5b8c3e8bcb1a9b1a6a.gif

················· 若川简介 ·················

你好,我是若川,毕业于江西高校。现在是一名前端开发“工程师”。写有《学习源码整体架构系列》20余篇,在知乎、掘金收获超百万阅读。
从2014年起,每年都会写一篇年度总结,已经写了7篇,点击查看年度总结。
同时,最近组织了源码共读活动,帮助3000+前端人学会看源码。公众号愿景:帮助5年内前端人走向前列。

d8fccdd8b8195b459b70aba180abf411.png

识别方二维码加我微信、拉你进源码共读

今日话题

略。分享、收藏、点赞、在看我的文章就是对我最大的支持~

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

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

相关文章

JS中变量和函数的使用

一、变量的介绍 1、啥是变量? 变量的本质是一块有名字的内存空间。变量由变量名和变量值构成。变量名指的是内存空间的别名,一般位于赋值运算符的左边;而变量值指的是内存空间中的数据,一般位于赋值运算符的右边。例如:var balanc…

Win32 API消息函数:GetMessagePos

Win32 API消息函数:GetMessagePos 函数功能:该函数返回表示屏幕坐标下光标位置的长整数值。此位置表示当上一消息由GetMessage取得时鼠标占用的点。 函数原型:DWORD GetMessagePos(VOID) 参数:无。 返回值&…

都快 2022 年了,这些 Github 使用技巧你都会了吗?

大家好,我是若川。最近组织了源码共读活动,感兴趣的可以点此加我微信 ruochuan12 参与,每周大家一起学习200行左右的源码,共同进步。同时极力推荐订阅我写的《学习源码整体架构系列》 包含20余篇源码文章。最近经常有小伙伴问我如…

单线程+异步协程

一 . 线程池和进程池 可以适当的使用,在大量的IO情况下有更好的方法 import time from multiprocessing.dummy import Pool def request(url):print(正在下载->,url)time.sleep(2)print(下载完毕->,url) start time.time() urls [www.baidu.com,www.taobao.com,www.sou…

Repeater\DataList\GridView实现分页,数据编辑与删除

一、实现效果 1、GridView 2、DataList 3、Repeater 二、代码 1、可以去Csdn资源下载,包含了Norwind中文示例数据库噢!(放心下,不要资源分) 下载地址:数据控件示例源码Norwind中文数据库 2、我的开发环境&a…

网站快速成型_我的老板对快速成型有什么期望?

网站快速成型Some of the top excuses I have gotten from clients when inviting them into a prototyping session are: “I am not a designer!” “I can’t draw!” “I have no creative background!”在邀请客户参加原型制作会议时,我从客户那里得到的一些主…

碎片化学前端,融入到积极上进的环境,我推荐~

众所周知,关注公众号可以了解学习掌握技术方向,学习优质好文,落实到自己项目中。还可以结交圈内好友,让自己融入到积极上进的技术氛围,促进自己的技术提升。话不多说,推荐这些优质前端公众号前端之神 80w阅…

重学JavaScript深入理解系列(六)

JavaScript深入理解—-闭包(Closures) 概要 本文将介绍一个在JavaScript经常会拿来讨论的话题 —— 闭包(closure)。闭包其实已经是个老生常谈的话题了; 有大量文章都介绍过闭包的内容,尽管如此,这里还是要试着从理论角…

EXT.NET复杂布局(四)——系统首页设计(上)

很久没有发帖了,很是惭愧,因此给各位使用EXT.NET的朋友献上一份礼物。 本篇主要讲述页面设计与效果,下篇将讲述编码并提供源码下载。 系统首页设计往往是个难点,因为往往要考虑以下因素: 重要通知系统功能菜单快捷操作…

figma设计_在Figma中使用隔片移交设计

figma设计I was quite surprised by how much the design community resonated with the concept of spacers since I published my 自从我发表论文以来,设计界对间隔件的概念产生了多少共鸣,我感到非常惊讶。 last story. It encouraged me to think m…

axios源码中的10多个工具函数,值得一学~

大家好,我是若川。最近组织了源码共读活动,感兴趣的可以点此加我微信 ruochuan12 参与,每周大家一起学习200行左右的源码,共同进步。同时极力推荐订阅我写的《学习源码整体架构系列》 包含20余篇源码文章。本文来自读者Ethan01投稿…

安装jenkins时出现 No such plugin: cloudbees-folder的解决办法

今天安装了一下jenkins,在初始化安装插件时出现“ No such plugin: cloudbees-folder”错误,根据网上的教程: 1、打开链接“http://ftp.icm.edu.pl/packages/jenkins/plugins/cloudbees-folder/”,在最下面找到并打开“latest”目…

寄充气娃娃怎么寄_我如何在5小时内寄出新设计作品集

寄充气娃娃怎么寄Over the Easter break, I challenged myself to set aside an evening rethinking the structure, content and design of my portfolio in Notion with a focus on its 在复活节假期,我挑战自己,把一个晚上放在一边,重新思…

基于Hbase的用户评分协同过滤推荐算法

基于Hbase的用户评分协同过滤推荐算法 作者: 张保维 2012-1-3 一、 概述 本文为推荐引擎设计的基础篇,介绍基于hbase 存储方式用户评分的方式进行推荐的主体算法及在分布式平台环境下的实现。由于推荐算法分支众多,我们先从简单及实用的算法…

最全 JavaScript Array 方法 详解

大家好,我是若川。最近组织了源码共读活动,感兴趣的可以点此加我微信 ruochuan12 参与,每周大家一起学习200行左右的源码,共同进步。同时极力推荐订阅我写的《学习源码整体架构系列》 包含20余篇源码文章。我们在日常开发中&#…

[译] React Hooks: 没有魔法,只是数组

[译] React Hooks: 没有魔法,只是数组 原文链接: medium.com/ryardley/r… 我是 React 新特性 Hooks 的粉丝。但是,在你使用 React Hooks的过程中,有一些看上去 很奇怪的限制 。在本文里,对于那些还在为了理解这些限制…

管理沟通中移情的应用_移情在设计中的重要性

管理沟通中移情的应用One of the most important aspects of any great design is the empathetic understanding of and connection to the user. If a design is ‘selfish’, as in when a product designed with the designer in mind and not the user, it will ultimatel…

网易前端进阶特训营,邀你免费入营!一举解决面试晋升难题!

网易等大厂的前端岗位一直紧缺,特别是资深级。最近一位小哥面进网易,定级P4(资深),总包60W,给大家带来真实面经要点分享。网易的要求有:1.对性能优化有较好理解,熟悉常用调试工具2.熟…

Feign的构建过程及自定义扩展功能

spring-cloud-openfeign-core-2.1.1.RELEASE.jar 中 HystrixFeign 的详细构建过程: EnableFeignClients -> FeignClientsRegistrar 扫描 Feign注解的类 -> FeignClientFactoryBean通过Targeter生产FeignClient -> Targeter通过Feign.Builder构建Feign ->…

angelica类似_亲爱的当归(Angelica)是第一个让我哭泣的VR体验

angelica类似It was a night just like any other night. I finished work for the day and closed my laptop. I had dinner and after an hour, I put on my Oculus Quest headset in order to begin my VR workout.就像其他任何夜晚一样, 这 是一个夜晚。 我完成…