位置: IT常识 - 正文

Vue中的Pinia状态管理工具 | 一篇文章教会你全部使用细节(vue pending)

编辑:rootadmin
Vue中的Pinia状态管理工具 | 一篇文章教会你全部使用细节 文章目录Pinia状态管理Pinia和Vuex的对比Pinia基本使用🍤创建Pinia🍤创建StorePinia核心概念State🍟state基本使用🍟state其他操作Pinia核心Getters🍕getters基本使用🍕getters其他操作Pinia核心Actions🥧Actions基本使用🥧Actions异步操作Pinia状态管理Pinia和Vuex的对比

推荐整理分享Vue中的Pinia状态管理工具 | 一篇文章教会你全部使用细节(vue pending),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:vuex几种状态,vue状态管理使用,vue 状态管理干什么的,vuex状态管理几种状态,vue状态管理使用,vue的状态改变方式,vue状态机,vue状态管理使用,内容如对您有帮助,希望把文章链接给更多的朋友!

Pinia(发音为/piːnjʌ/,如英语中的“peenya”)是最接近piña(西班牙语中的菠萝)的词;

Pinia开始于大概2019年,最初是作为一个实验为Vue重新设计状态管理,让它用起来适合组合式API(Composition API)。

从那时到现在,最初的设计原则依然是相同的,并且目前同时兼容Vue2、Vue3,也并不要求你使用Composition API;

Pinia本质上依然是一个状态管理的库,用于跨组件、页面进行状态共享(这点和Vuex、Redux一样);

那么我们不是已经有Vuex了吗?为什么还要用Pinia呢?

Pinia 最初是为了探索 Vuex 的下一次迭代会是什么样子,结合了 Vuex 5 核心团队讨论中的许多想法;

最终,团队意识到Pinia已经实现了Vuex5中大部分内容,所以最终决定用Pinia来替代Vuex;

与 Vuex 相比,Pinia 提供了一个更简单的 API,具有更少的仪式,提供了 Composition-API 风格的 API;

最重要的是,在与 TypeScript 一起使用时具有可靠的类型推断支持;

和Vuex相比,Pinia有很多的优势:

优势一: mutations 不再存在:

他们经常被认为是非常冗长;他们最初带来了 devtools 集成,但这不再是问题;

优势二: 更友好的TypeScript支持,Vuex之前对TS的支持很不友好;

优势三: 不再有modules的嵌套结构:

你可以灵活使用每一个store,它们是通过扁平化的方式来相互使用的;

优势四: 也不再有命名空间的概念,不需要记住它们的复杂关系;

Pinia基本使用🍤创建Pinia

使用Pinia之前,我们需要先对其进行安装:

yarn add pinia

npm install pinia

使用pinia我们需要在单独的js文件中创建一个pinia, 并且在main.js中将其注册, 如下:

这样我们项目中就已经存在pinia了

import { createPinia } from "pinia";// 创建piniaconst pinia = createPinia()// 导出piniaexport default piniaimport { createApp } from 'vue'import App from './App.vue'// 导入piniaimport pinia from './stores'const app = createApp(App)// 注册piniaapp.use(pinia)app.mount('#app')🍤创建Store

什么是Store?

一个 Store (如 Pinia)是一个实体,它会持有为绑定到你组件树的状态和业务逻辑,也就是保存了全局的状态;

它有点像始终存在,并且每个人都可以读取和写入的组件;

你可以在你的应用程序中定义任意数量的Store来管理你的状态;

Store有三个核心概念(接下来会一一讲到):

state、getters、actions;

等同于组件的data、computed、methods;

一旦 store 被实例化,你就可以直接在 store 上访问 state、getters 和 actions 中定义的任何属性;

定义一个Store:

Store 是使用 defineStore() 定义的, 我们一般都会在一个单独的js的文件创建store, 不同组件的数据, 我们会定义在不同的js文件中创建不同的store

由于pinia中可以定义多个store, 所以每一个store它都需要一个唯一名称,作为第一个参数传递;

// 定义关于counter的storeimport { defineStore } from "pinia"// 调用defineStore定义store, defineStore返回一个函数const useCounter = defineStore("counter", { state: () => ({ counter: 101 })})// 将useCounter函数导出export default useCounter

第一个参数 name,也称为 id,是必要的,Pinia 使用它来将 store 连接到 devtools。

Vue中的Pinia状态管理工具 | 一篇文章教会你全部使用细节(vue pending)

defineStore()返回的函数统一使用useXXX作为命名方案, 且XXX一般就使用传入的id,这是约定的规范;

调用defineStore()返回的函数才会创建store

Store在它被使用之前是不会创建的,我们可以通过调用use函数来使用Store:

<template> <!-- 展示counterStore.counter的状态 --> <h2>{{ counterStore.counter }}</h2></template><script setup> // 导入我们自定义关于counter的store import useCounter from '../stores/counter'; // 调用函数才会创建store, 不调用不会创建 const counterStore = useCounter()</script>

注意Store获取到后, 如果我们想要对其解构, 不能直接解构,直接解构的话会失去响应式:

为了从 Store 中提取属性同时保持其响应式我们有两种方式

方式一: 解构时包裹一层toRefs

方式二: pinia给我们提供了一个方法, 使用storeToRefs()方法可以保持数据的响应式。

方式一

<script setup> import { toRefs } from 'vue'; import useCounter from '../stores/counter'; const counterStore = useCounter() // 包裹一层toRefs const { counter } = toRefs(counterStore)</script>

方式二

<script setup> import { storeToRefs } from 'pinia'; import useCounter from '../stores/counter'; const counterStore = useCounter() // 包裹一层storeToRefs const { counter } = storeToRefs(counterStore)</script>Pinia核心概念State🍟state基本使用

state 是 store 的核心部分,因为store是用来帮助我们管理状态的。

在 Pinia 中,状态被定义为返回初始状态的函数;

前面我们创建了一个counter.js文件用于定义counter的store, 接下来我们创建一个urse.js文件, 定义一个用户信息的store来演示state

在pinia中state和vuex中一样, state是一个函数, 返回一个对象

import { defineStore } from "pinia"const useUser = defineStore("user", { // state定义状态 state: () => ({ name: "chenyq", age: 18, height: 1.88 })})export default useUser

将定义的Store展示到组件中

<template> <div class="home"> <!-- 展示userStore中的状态 --> <h2>{{ name }}</h2> <h2>{{ age }}</h2> <h2>{{ height }}</h2> </div></template><script setup> import { storeToRefs } from 'pinia'; // 导入我们自定义的store import useUser from "../stores/user" // 调用函数创建store const userStore = useUser() // 将store中的状态解构出来 const { name, age, height } = storeToRefs(userStore)</script>🍟state其他操作

读取和写入 state

默认情况下,您可以通过 store 实例访问状态来直接读取, 刚刚我们就是这样读取状态的

写入状态其实也同理, 通过store实例访问状态直接修改

<template> <div class="home"> <!-- 展示userStore中的状态 --> <h2>{{ name }}</h2> <h2>{{ age }}</h2> <h2>{{ height }}</h2> <button @click="changeInfo">修改信息</button> </div></template><script setup> import { storeToRefs } from 'pinia'; import useUser from "../stores/user" const userStore = useUser() const { name, age, height } = storeToRefs(userStore) function changeInfo() { // 使用实例访问状态, 进行修改 userStore.name = "王老五" userStore.age = 20 userStore.height = 1.89 }</script>

重置 State

当我们对某些状态进行了修改之后, 我们可以通过调用 store 上的 $reset() 方法将状态 重置到其初始值;

$reset()方法会将所有的状态重置到初始值

<template> <div class="home"> <!-- 展示userStore中的状态 --> <h2>{{ name }}</h2> <h2>{{ age }}</h2> <h2>{{ height }}</h2> <button @click="changeInfo">修改信息</button><button @click="resetInfo">重置信息</button> </div></template><script setup> import { storeToRefs } from 'pinia'; import useUser from "../stores/user" const userStore = useUser() const { name, age, height } = storeToRefs(userStore) function changeInfo() { userStore.name = "王老五" userStore.age = 20 userStore.height = 1.89 }function resetInfo() { // 重置状态 userStore.$reset() }</script>

同时修改多个状态

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

<template> <div class="home"> <!-- 展示userStore中的状态 --> <h2>{{ name }}</h2> <h2>{{ age }}</h2> <h2>{{ height }}</h2> <button @click="changeInfo">修改信息</button> </div></template><script setup> import { storeToRefs } from 'pinia'; import useUser from "../stores/user" const userStore = useUser() const { name, age, height } = storeToRefs(userStore) function changeInfo() { // $patch一次性修改多个状态 userStore.$patch({ name: "罗三炮", age: 50, height: 1.58 }) }</script>Pinia核心Getters🍕getters基本使用

Getters相当于Store的计算属性:

它们可以用 defineStore() 中的 getters 属性定义;

getters中可以定义接受一个state作为参数的函数;

在defineStore中定义gettersimport { defineStore } from "pinia"const useCounter = defineStore("counter", { state: () => ({ counter: 101 }), // 定义getters getters: { doubleCounter(state) { return state.counter * 2 } }})export default useCounter直接通过store对象就可以访问当前store的Getters<template> <!-- 访问当前store的Getters --> <h2>{{ counterStore.doubleCounter }}</h2></template><script setup> import useCounter from "../stores/counter" const counterStore = useCounter()</script>🍕getters其他操作

Getters中访问自己的其他Getters

我们可以通过this来访问到当前store实例的所有其他属性;

this相当于是绑定的store实例

例如在getter中访问自己的doubleCountergetters: { doubleCounter(state) { return state.counter * 2 }, doubleCounterAddOne() { return this.doubleCounter + 1 }}

Getters也可以返回一个函数,这样就可以接受参数:

const useCounter = defineStore("counter", { state: () => ({ counter: 101, friend: [ {id: 111, name: "chenyq"}, {id: 112, name: "王老五"}, {id: 113, name: "罗三炮"}, ] }), getters: { // getter可以返回一个函数 getfriendById() { return (id) => { return this.friend.find(item => item.id == id) } } }})<h2>{{ counterStore.getfriendById(111) }}</h2><h2>{{ counterStore.getfriendById(112) }}</h2>

当前Getters访问其他store中的state/getters

// 导入usrUserimport useUser from "./user"const useCounter = defineStore("counter", { state: () => ({ counter: 101 }), getters: { showMessage(state) { // 拿到userStore对象, 获取userStore中的信息 const userStore = useUser() // 返回自己store的信息拼接上userStore中的信息 return `${state.counter}${userStore.name}` } }})<h2>{{ counterStore.showMessage }}</h2>Pinia核心Actions🥧Actions基本使用

Actions 相当于组件中的 methods。

可以使用 defineStore() 中的 actions 属性定义,并且它们非常适合定义业务逻辑;

和getters一样,在action中可以通过this访问整个store实例的所有操作;

const useCounter = defineStore("counter", { state: () => ({ counter: 101 }), actions: { increment() { this.counter++ } }})<h2>{{ counterStore.counter }}</h2><button @click="changeState">+1</button><script setup> import useCounter from "../stores/counter" const counterStore = useCounter() function changeState() { // 通过store实例调用即可 counterStore.increment() }</script>🥧Actions异步操作

Actions中是支持异步操作的,并且我们可以编写异步函数,在函数中使用await

例如在Actions发生网络请求

import { defineStore } from 'pinia'const useHome = defineStore("home", { state: () => ({ // 定义空数组用于接收网络请求数据 banners: [], recommends: [] }), actions: { // 支持异步操作 async fetchHomeMultidata() { // 发送网络请求获取数据 const res = await fetch("http://123.207.32.32:8000/home/multidata") const data = await res.json() // 将获取的数据添加到state中 this.banners = data.data.banner.list this.recommends = data.data.recommend.list } }})export default useHome

展示网络请求获取到homeStore中的数据

<template> <div class="about"> <ul v-for="item in homeStore.banners" :key="item.acm"> <li>{{ item.title }}</li> </ul> </div></template><script setup> import useHome from "../stores/home" const homeStore = useHome() // 告知发送网络请求 homeStore.fetchHomeMultidata()</script>
本文链接地址:https://www.jiuchutong.com/zhishi/297716.html 转载请保留说明!

上一篇:node npm 下载,安装,使用 全网最全教程(npm安装node指定版本)

下一篇:最通俗易懂的LSTM讲解,一个例子理解通透!!(最通俗易懂的电动力学教材)

  • 苹果手机怎么恢复删除的照片(苹果手机怎么恢复数据)

    苹果手机怎么恢复删除的照片(苹果手机怎么恢复数据)

  • vivox70pro+怎么打开开发者模式(vivox70pro+如何)

    vivox70pro+怎么打开开发者模式(vivox70pro+如何)

  • 微信新建用户信息怎么修改性别(微信新建用户信息怎么删除)

    微信新建用户信息怎么修改性别(微信新建用户信息怎么删除)

  • 小米电池bn45是什么手机(小米电池bn41)

    小米电池bn45是什么手机(小米电池bn41)

  • 苹果7的耳机是什么口(苹果7的耳机是什么型号)

    苹果7的耳机是什么口(苹果7的耳机是什么型号)

  • 抖音收不到短信验证码(抖音收不到短信验证码怎么回事)

    抖音收不到短信验证码(抖音收不到短信验证码怎么回事)

  • 钉钉直播能投屏到电视吗(钉钉直播能投屏到小度上吗)

    钉钉直播能投屏到电视吗(钉钉直播能投屏到小度上吗)

  • iphonexsmax怎么清除用过的程序(iPhonexsmax怎么清理内存)

    iphonexsmax怎么清除用过的程序(iPhonexsmax怎么清理内存)

  • 微信每天加多少人会被限制(微信每天加多少好友会被限制)

    微信每天加多少人会被限制(微信每天加多少好友会被限制)

  • win7旗舰版64位C盘多大

    win7旗舰版64位C盘多大

  • wps怎么删除竖线(wps里面的竖线怎么删掉)

    wps怎么删除竖线(wps里面的竖线怎么删掉)

  • 路由器卫士账号密码是什么(路由器卫士账号密码错误)

    路由器卫士账号密码是什么(路由器卫士账号密码错误)

  • 小米路由器3g是千兆吗(小米路由器3G是千兆端口还是百兆端口)

    小米路由器3g是千兆吗(小米路由器3G是千兆端口还是百兆端口)

  • ipad air3续航时间(ipad air3 续航)

    ipad air3续航时间(ipad air3 续航)

  • bug是漏洞的意思吗(bug和漏洞的区别)

    bug是漏洞的意思吗(bug和漏洞的区别)

  • ipad3网速很慢什么原因(ipad网速太差了)

    ipad3网速很慢什么原因(ipad网速太差了)

  • word字体横行变竖行(word字体横排变竖排)

    word字体横行变竖行(word字体横排变竖排)

  • airpods怎么连接ipad(airpods怎么连接iPod)

    airpods怎么连接ipad(airpods怎么连接iPod)

  • 苹果xr支持18w快充吗(苹果xr支持18w快冲吗)

    苹果xr支持18w快充吗(苹果xr支持18w快冲吗)

  • 微信运动怎么显示公里(微信运动怎么显示手表健身记录)

    微信运动怎么显示公里(微信运动怎么显示手表健身记录)

  • 抖音顶上面那个怎么设置(抖音里面的顶字是什么意思)

    抖音顶上面那个怎么设置(抖音里面的顶字是什么意思)

  • 酷狗如何降调(酷狗如何降调音效)

    酷狗如何降调(酷狗如何降调音效)

  • 美团众包如何注销账号(美团众包如何注册)

    美团众包如何注销账号(美团众包如何注册)

  • 手机号被标记快递送餐怎么取消(手机号被标记快递外卖)

    手机号被标记快递送餐怎么取消(手机号被标记快递外卖)

  •  电话打通了一直没人接(电话打了就通话)

    电话打通了一直没人接(电话打了就通话)

  • 电脑怎么安装双系统?Win11 和 Win7双系统安装图文教程(电脑怎么安装双显卡)

    电脑怎么安装双系统?Win11 和 Win7双系统安装图文教程(电脑怎么安装双显卡)

  • 数字马力前端笔试编程(数字马力前端笔试题rgb)

    数字马力前端笔试编程(数字马力前端笔试题rgb)

  • 保本理财增值税可以开票吗怎么开
  • 商业保险进项税额转出影响成本吗
  • 行政单位利息收入可以扣除手续费
  • 金融商品转让和持有至到期都需要缴纳增值税吗
  • 漏缴的印花税如何补交
  • 劳务公司如何避税与避费
  • 无发票入账违反哪条法律
  • 金蝶迷你版会计科目代码格式
  • 税务登记财务负责人可以是法人吗
  • 跨月红冲发票如何申报退税
  • 担保费能抵扣吗
  • 自产的产品无偿赠送职工
  • 通讯费企业所得税计算
  • 广告业务增值税
  • 拓展培训费如何开票
  • 雇主责任险税前列支
  • 企业所得税计提分录怎么写
  • 资金账簿印花税最新政策2022年
  • 税务局领普通发票需要多少钱
  • 增值税优惠的二级明细科目
  • 外商投资企业外债额度
  • 私营公司可以构成单位犯罪吗
  • 会计新手入门
  • 货物装卸过程中由于操作不当或违反操作规程
  • ami bios怎么设置u盘启动
  • 如何设置win7系统密码
  • 苹果手机录音怎么转换成mp3格式
  • windows10如何关机
  • windows未能正常启动
  • 开发商自用房产出售成为二手房土地成本
  • 贷款滞纳金如何收取
  • 企业财务人员如何防范电信诈骗
  • 企业借款费用处理不当会产生什么样的后果呢?
  • uniapp引入全局scss
  • 布鲁克斯岭
  • 约克大教堂是基督教吗
  • iconfont原理
  • 一般纳税人两费附加减免规定
  • jvm调优思路
  • 个税租房租金扣除规则
  • 成品油涉及范围有哪些
  • 金蝶财务软件库存商品数量金额再那查看
  • mysql常见报错
  • 公司财务报表中不设其他综合收益项目可以吗
  • 无形资产摊销计算方法
  • 建筑工程租赁费属于什么费用
  • 主营业务收入借贷方
  • 企业广告费以后会涨吗
  • 股权转让对价款如何计算
  • 物业公司收物业费不开发票违法吗
  • 劳务派遣的工资是谁发的
  • 房地产成本的概念
  • 管理费用和销售费用属于什么科目
  • 公司发放给员工的福利又要回
  • 购买超市购物卡有优惠吗
  • 工程与会计
  • 年初建账考虑要点有哪些
  • mysql 临时表
  • win8专业版系统更改电脑设置没反应
  • 如何自己解封微信号呢
  • linux内核模块编译步骤
  • freebsd怎么样
  • 安装win7需要激活吗
  • win8怎么玩帝国时代2
  • msswchx.exe - msswchx进程是什么文件 有何作用
  • windows7如何关闭update
  • win10周年纪念版
  • 在linux中使用什么命令可以执行shell脚本
  • unity3d ugui优化
  • 表单元素的属性
  • jquery事件的响应
  • unity数据结构和算法
  • androidstudio的jdk
  • c# for unity
  • 封装是借助什么达到的
  • jquery使用css方法添加图片边框视频教学
  • 黑龙江电子税务局app手机
  • 小程序河南税务局
  • 河南省地税局副局长
  • 税控盘打不开
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设