Simonzhangs' blog Simonzhangs' blog
首页
  • 前端文章

    • HTML
    • CSS
    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • JS设计模式总结
  • 《Vue》
  • 《React》
  • 《TypeScript 从零实现 axios》
  • TypeScript
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • apple music
  • extension
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Simonzhangs

前端学习探索者
首页
  • 前端文章

    • HTML
    • CSS
    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • JS设计模式总结
  • 《Vue》
  • 《React》
  • 《TypeScript 从零实现 axios》
  • TypeScript
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • apple music
  • extension
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 基础

  • 组件

  • 过渡&动画

  • 可复用性&组合

  • 工具

  • 规模化

  • Vuex

  • Pinia

    • Vue3中状态管理pinia学习
      • 1.Pinia简介
      • 2.Pinia开发环境搭建
        • Vue3环境安装
        • Pinia的安装
        • 在main.ts中引入Pinia
        • 创建store状态管理库
        • 在Vue3组件中读取store数据
        • 实现状态数据的改变
        • 状态数据读取时注意事项
        • 通过对象读取方法
        • 通过$patch修改多条数据
        • 直接在acitons中写好逻辑,再调用actions
        • getters使用
        • getters编写时this使用
        • getters缓存特性
        • 新建一个store容器
        • 在另一个容器中引入
        • vue-devtools安装
        • vue-devtools对Pinia的调试
  • 其他

  • 《Vue》笔记
  • Pinia
simonzhangs
2022-04-07
目录

Vue3中状态管理pinia学习原创

vue3成为默认版本,pinia状态管理是vue官方人员出的,比vuex更加方便。它有以下几个优点:

  • 同时支持vue2和vue3
  • 状态管理库的简化,只有state、getters、actions
  • 不需要嵌套模块,符合vue3的Composition api
  • typescript支持
  • 代码更加简洁

我跟着一块了解了下pinia状态管理的环境搭建、store创建、状态数据改变方式以及注意事项、还包括getters使用以及store的相互调用方面内容。

# 一、Pinia简介和开发环境搭建

# 1.Pinia简介

Pinia是Vue生态里Vuex的代替者,一个全新Vue的状态管理库。Pinia的优势就是:更加简洁的语法,完美支持Vue3的Composition api 和对 TypeScript 的完美支持。

# 2.Pinia开发环境搭建

# Vue3环境安装

Pinia是Vue的状态管理库,所以首先需要创建Vue的项目环境,我采用的是Vite来搭建Vue3环境。(也可以用Webpack来搭建,哪个熟悉用哪个)

①初始化vitenpm init vite@latest

②输入项目名称? Project name: » vite-project,这里我起名vite-pinia-demo

③选择项目框架,这里选择vue或者vue-ts,我这里选择vue-ts

? Select a framework: » - Use arrow-keys. Return to submit.
>   vanilla
    vue
    react
    preact
    lit
    svelte
1
2
3
4
5
6
7

④现在项目已经初始化完成,按照下面提示顺序来跑通Vue3项目

Done. Now run:
cd vite-pinia-demo
  npm install
  npm run dev
1
2
3
4

⑤直到出现下列代码,复制网址能够正常访问页面说明Vue3项目环境初步搭建好了。

vite v2.8.3 dev server running at:

  > Local: http://localhost:3000/
  > Network: use `--host` to expose

  ready in 392ms.
1
2
3
4
5
6

# Pinia的安装

Vue3环境搭建好了后,开始安装Pinia状态管理库。

安装pinia:npm install pinia

如何确认安装成功:在项目文件夹根目录中package.json文件中确认依赖项中是否存在pinia。

"dependencies": {
    "pinia": "^2.0.11",
    "vue": "^3.2.25"
  }
1
2
3
4

# 二、用Pinia的方式创建一个store

# 在main.ts中引入Pinia

在/src/main.ts中需要引入Pinia,因为main.ts是Vue3项目中根实例引入的文件

首先引入Pinia,import {createPinia} from 'pinia'

然后创建pinia实例,const pinia = createPinia()

最后将pinia实例挂载到Vue的根实例上

const app = createApp(App)

//挂载到 Vue 根实例上
app.use(pinia)
app.mount('#app')
1
2
3
4
5

# 创建store状态管理库

首先在/src目录下,新建状态管理store文件夹,并在该文件夹下创建一个index.ts状态管理文件;

在状态管理index.ts文件中:

  1. 定义状态容器
  2. 修改容器中的state
  3. 容器中getters和actions的使用

书写格式如下:

import { defineStore } from "pinia"

export const myStore = defineStore('myStore',{
    state:()=>{
        return{}
    },
    getters:{},
    actions:{}
})
1
2
3
4
5
6
7
8
9

defineStore()方法接收两个参数:

第一个参数是容器的名字,需要保证是唯一的;

第二个参数是要配置的对象,包括以下三个属性:

  • state:存储全局状态;
  • getters:类似于Vue中的计算属性,用来计算状态的变化,具有缓存的功能
  • actions:针对state状态数据来编写复杂的业务逻辑代码

# 在Vue3组件中读取store数据

首先在/src/store/index.ts的state中添加数据:

state:()=>{
        return{
            data:'Hello Pinia!'
        }
    },
1
2
3
4
5

然后在/src/components/下新建一个组件piniaTest.vue:

<template>
    <h2>{{store.data}}</h2>
</template>
<script lang="ts" setup>
import { myStore } from '../store/index.'
const store = myStore()
</script>
<style scoped>
</style>
1
2
3
4
5
6
7
8
9

再将piniaTest.vue组件引入到App.vue中:

<script setup lang="ts">
import piniaTestVue from './components/piniaTest.vue';
</script>

<template>
  <piniaTestVue/>
</template>

<style>
</style>
1
2
3
4
5
6
7
8
9
10

重新在终端输入npm run dev运行,打开网页可以看到状态管理库中存储的数据“Hello Pinia!",则完成了Pinia状态管理库的构建并可以在其他组件中使用状态管理数据!

# 三、Pinia改变状态数据和注意方式

# 实现状态数据的改变

上一节中实现了对于状态数据的读取,步骤是:首先引入状态管理库,然后实例化,再通过对象引用的方式读取状态数据。这一节再来验证一下状态数据的改变,步骤和读取类型,只不过是加入一个方法来对状态数据进行改变,来看状态数据是否可以响应式更新在界面上。

首先在store/index.ts中state加入新的状态数据count:

state:()=>{
        return{
            data:'Hello Pinia!',
            count:0
        }
    },
1
2
3
4
5
6

再components文件夹下新建一个组件piniaChange.vue:

<template>
    <div><button @click="handleClick">点击count加1</button></div>
</template>
<script lang="ts" setup>
import { myStore } from '../store/index.'
const store = myStore()

const handleClick = ()=>{
    store.count++
}
</script>
<style scoped>
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13

然后将此组件也引入到App.vue中:

import piniaChangeVue from './components/piniaChange.vue';

<template><piniaChangeVue/></template>
1
2
3

但是count数据还未加入在组件中去,所以还测试不了count数据变化,选择把count状态数据加入上一节创建的piniaTest.vue中:

<template>
    <h2>{{store.data}}</h2>
    <h2>count:{{store.count}}</h2>
</template>
1
2
3
4

最后,重新跑下项目,通过点击按钮就可以在页面上响应式看到count的改变。好啦,通过一顿操作验证了状态数据的改变。

# 状态数据读取时注意事项

在读取状态数据时,之前采用的方式是通过引入状态文件,实例化对象,再到对象读取的方式。可以通过对实例化对象结构的方式来读取数据:

<template>
    <h2>{{store.data}}</h2>
    <h2>count:{{store.count}}</h2>
    <hr>
    <h2>{{data}}</h2>
    <h2>count:{{count}}</h2>
</template>
<script lang="ts" setup>
import { myStore } from '../store/index.'
const store = myStore()

const {data,count} = store
</script>
<style scoped>
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

但是直接解构得到的数据并不是响应式数据,当count数据改变时,解构的数据并不会跟着发生变化。

解决办法:通过在pinia引入storeToRefs()方法,解构时对要解构的对象采用此方法,可以实现数据响应式变化了。

# 四、Pinia改变状态数据的四种方式

# 通过对象读取方法

前一节就是采用这种方法的读取并改变状态数据的。适用于简单的业务逻辑数据改变。

# 通过$patch修改多条数据

首先创建方法:

const handleClickPatch = ()=>{
    store.$patch({
        count:store.count + 2,
    })
}
1
2
3
4
5

然后通过按钮调用该方法:

    <div><button @click="handleClickPatch">Patch点击count加2</button></div>
1

优点:可以在$patch方法中写入多条状态数据改变,同时此方法是官方经过优化的,相比于直接修改来说修改速度更快,适用于多条数据同时更新状态。

# 直接在acitons中写好逻辑,再调用actions

在/store/index.ts的actions中写入actions:

actions:{
        changeState(){
            this.count++
            this.data = 'Hello Actions'
        }
    }
1
2
3
4
5
6

然后通过调用该actions:

    <div><button @click="store.changeState()">Action点击count加1</button></div>
1

注意:actions中方法书写不能使用箭头函数,否则this指向位置发生错误。

# 五、Pinia中getters的使用

# getters使用

getters与vue中的计算属性很相似,用于在获取状态数据时做一些处理。比如说state状态中有word状态数据,输出时想要保证是全大写的,以此为例。

首先增加word状态数据:

 state:()=>{
        return{
            data:'Hello Pinia!',
            count:0,
            word:'Lowcase'
        }
    },
1
2
3
4
5
6
7

书写getters:

getters:{
        wordToUpper(state){
            return state.word.toLocaleUpperCase()
        }
    },
1
2
3
4
5

在组件中引入和调用:

const {data,count,wordToUpper} = storeToRefs(store)

<h2>{{wordToUpper}}</h2>
1
2
3

重新跑通系统,可以看到word状态数据都变为大写的。

# getters编写时this使用

在书写getters时,可以传入state参数,直接在内容使用this来代替state。

# getters缓存特性

getters具有缓存特性,当多次调用getters内同一个函数时,它只会执行一次调用。

可以在getters内函数打印调用信息来验证,当多次调用该函数时,发现控制台只打印了一次调用信息。

getters:{
        wordToUpper(state){
            console.log('wordToUpper被调用了!')
            return state.word.toLocaleUpperCase()
        }
    },
1
2
3
4
5
6

当状态数据发生改变时,被调用的函数才会重新执行一次,不管是有多少地方调用该函数。

通过按钮调用改变状态数据方法可以验证:

const handleClickToUpper = ()=>{
    store.word = 'pinia'
}
1
2
3

点击按钮后,即使有多处调用getters,控制台仍只打印一次调用信息。

# 六、Pinia中store的相互调用

pinia状态管理中有多个store时,就会涉及store间的相互调用。

# 新建一个store容器

在/src/store下新建文件another.ts:

import { defineStore } from "pinia";

export const anotherStore = defineStore('anotherStore',{
    state:()=>{
        return{
            songsList:['love story','lover','All to well']
        }
    },
    getters:{},
    actions:{}
})
1
2
3
4
5
6
7
8
9
10
11

# 在另一个容器中引入

在index.ts中引入新建的store容器:

import { anotherStore } from '../store/another';
1

在index.ts中actions中调用另一个store状态数据

actions:{
        changeState(){
            this.count++
            this.data = 'Hello Actions'
        },
        getSongList(){
            console.log(anotherStore().songsList)
        }
    }
1
2
3
4
5
6
7
8
9

再通过组件定义按钮来调用actions方法:

    <div><button @click="store.getSongList">getList</button></div>
1

点击按钮可以看到控制台打印出信息,即完成了store间的调用。

# 七、Pinia在开发中用vue-devtools的调试方法

# vue-devtools安装

vue-devtools是很好用的vue调试工具,可以在谷歌商店下载或者在github上下载自己跑通再安装。

# vue-devtools对Pinia的调试

安装后打开控制台的vue选项卡,可以看到vue中引入的组件;

组件中显示小菠萝图标的就是代表store状态容器;还可以在组件中筛选出使用pinia状态管理的组件。

以上是Pinia开发环境搭建和基础学习的内容了,完整示例代码上传到了github上,链接 (opens new window)。


参考链接:

  • Pinia入门视频教程 全新一代状态管理工具Pinia -Vue3全家桶系列 (opens new window)
  • Pinia 快速入门 (opens new window)
  • Pinia官方网站 (opens new window)
编辑 (opens new window)
上次更新: 2022/04/07, 19:26:26
Vuex
虚拟DOM和diff算法

← Vuex 虚拟DOM和diff算法→

最近更新
01
一些有意思的类比
06-16
02
the-super-tiny-compiler解析
06-06
03
计算机编译原理总概
06-06
更多文章>
Theme by Vdoing | Copyright © 2021-2022
蜀ICP备2021023197号-2
Simonzhans | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
  • 飙升榜
  • 新歌榜
  • 云音乐民谣榜
  • 美国Billboard榜
  • UK排行榜周榜