Vue新一代状态管理工具Pinia的具体使用

作者:吴同学丫 时间:2024-05-09 15:11:53 

前言

Pinia是尤雨溪强烈推荐的一款Vue状态管理工具,也被认为是下一代Vuex的替代产品。

优点

  • 去除了mutations,只有 state,getters和actions,其中actions支持了同步和异步操作

  • 不会像Vuex那样有模块嵌套,Pinia只有store的概念,store之间可以相互使用,互不影响,达到模块扁平化的效果

  • 更好地支持ts

  • 更好地支持Vue2/Vue3

  • 逻辑更加清晰,开发起来更加简单

安装

npm i pinia

创建并挂载

1.在src目录下新建store目录并在其下面创建index.js文件,代码如下:

import { createPinia } from 'pinia'
const store = createPinia()
export default store

2.在main.js中引入store并挂载,代码如下:

import { createApp } from 'vue'
import App from './App.vue'
import store from './store/index'

createApp(App)
.use(store)
.mount('#app')

创建store

在src/store文件夹下创建一个js文件,命名按照需求即可,我这边定义为main.js,代码如下:

import { defineStore } from 'pinia'
export const mainStore = defineStore('main', {
   state: () => {
       return {
           msg: 'hello',
           count: 1
       }
   },
   actions: {},
   getters: {}
})

其中defineStore的第一个参数为该store的名称,第二个参数为一个对象,包含了该store的state,getters和actions,state改为了函数形式,目的应该是像Vue2 options API中的data类似,避免多个store中定义的属性相互受到影响。

使用store

此处使用Vue3的SFC语法,主要是Pinia更适合Vue3这种组合式API风格,方便演示

回显与修改state

<script lang="ts" setup>
   import { mainStore } from '../store/main'
   import { storeToRefs } from 'pinia'

const store = mainStore()
   const { count } = storeToRefs(store)

// 单条数据直接修改
   const handleAddCount = () => {
       store.count++
   }
</script>

<template>
   <div>
       <p>{{ store.msg }}</p>
       <p>{{ count }}</p>
       <button @click="handleAddCount">+</button>
   </div>
</template>
  • 使用方法与Vuex基本类似,要使用哪个store,就直接进行引入,非常方便,没那么多层级引用

  • 其中,我们使用了Pinia中的storeToRefs方法,此方法能够直接解构出该store的state中的某个值,并且是响应式的;如果我们直接从state上解构,那么解构出的值就不是响应式的了。

  • 如果我们要修改state中的值,不能直接去修改解构出的值,得去修改state上对应的属性

使用$patch对多条数据直接修改

使用$patch的方式对数据进行修改,可以加快修改速度,性能更好。$patch 方法可以接受两种类型的参数,对象型和回调函数型。

$patch + 对象

$patch + 函数  注:使用回调函数型时,回调接收一个state参数,state指代的就是对应store中的state

使用方式如下:

<script lang="ts" setup>
   import { mainStore } from '../store/main'
   import { storeToRefs } from 'pinia'

const store = mainStore()
   const { count } = storeToRefs(store)

// 使用$patch + 对象
   const updateWithObj = () => {
       store.$patch({
           msg: store.msg === 'hello' ? 'hello world' : 'hello',
           count: store.count + 2
       })
   }
   // 使用$patch + 回调
   const updateWithFun = () => {
       store.$patch((state) => {
           state.msg = state.msg === 'hello' ? 'hello world' : 'hello'
           state.count = state.count + 3
       })
   }
</script>

<template>
   <div>
       <p>{{ store.msg }}</p>
       <p>{{ count }}</p>
       <button @click="updateWithObj">$patch+对象</button>
       <button @click="updateWithFun">$patch+回调</button>
   </div>
</template>

使用actions

1.在src/store/main.js的actions对象中,添加一个方法,代码如下:

import { defineStore } from 'pinia'
export const mainStore = defineStore('main', {
   state: () => {
       return {
           msg: 'hello',
           count: 1
       }
   },
   actions: {
       changeState() {
           this.count++
           this.msg = this.msg === 'hello' ? 'hello world' : 'hello'
       }
   },
   getters: {}
})

2.使用方式为:store.方法名,代码如下:

<script lang="ts" setup>
   import { mainStore } from '../store/main'
   import { storeToRefs } from 'pinia'

const store = mainStore()
   const { count } = storeToRefs(store)

// 使用action修改数据
   const onActionClick = () => {
       store.changeState()
   }
</script>

<template>
   <div>
       <p>{{ store.msg }}</p>
       <p>{{ count }}</p>
       <button @click="onActionClick">使用action</button>
   </div>
</template>

使用getters

Pinia中的getter和Vue中的计算属性类似,在获取state之前会进行处理,具有缓存性,如果值没有改变,即使多次调用,实际上也只会调用一次。

1.在src/store/main.js的getters对象中进行添加,代码如下:

import { defineStore } from 'pinia'
export const mainStore = defineStore('main', {
   state: () => {
       return {
           msg: 'hello',
           count: 1
       }
   },
   getters: {
       getState(state) {
           console.log('getState被调用了');

// getter 中不仅可以传递state直接改变数据,也可以使用this来改变数据
           return `${state.msg} + ${this.count}`
       }
   }
})

2.使用方式如下:

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

<template>
   <div>
       <p>使用getter获取数据:{{ store.getState }}</p>
       <p>使用getter获取数据:{{ store.getState }}</p>
       <p>使用getter获取数据:{{ store.getState }}</p>
   </div>
</template>

我们可以看到,即使执行了三遍一样的代码,但最终还是只调用了一次。

Vue新一代状态管理工具Pinia的具体使用

多个store相互调用

在Pinia中,可以在一个store中import引入另外一个store,然后通过调用引入的store方法的形式,获取引入的store的状态。

1.在src/store目录下,新建一个文件.js,代码如下:

import { defineStore } from 'pinia'

export const userStore = defineStore('user', {
   state: () => {
       return {
           name: '吴同学'
       }
   }
})

2.在需要用到的store中进行引入,并通过getters的方式获取,代码如下:

import { defineStore } from 'pinia'
import { userStore } from './user'

export const mainStore = defineStore('main', {
   getters: {
       getUserState() {
           return userStore().name
       }
   }
})

数据持久化

Pinia与Vuex一样,刷新页面后,数据就会重置,有时候我们需要将数据进行持久化存储,我们可以使用pinia-plugin-persist这个插件

安装

npm i pinia-plugin-persist --save

使用

1.在src/store/index.js文件夹下,引入并使用,代码如下:

import { createPinia } from 'pinia'
import piniaPluginPersist from 'pinia-plugin-persist'

const store = createPinia()
store.use(piniaPluginPersist)

export default store

2.在对应的store里开启持久化存储

import { defineStore } from 'pinia'
import { userStore } from './user'

export const mainStore = defineStore('main', {
   state: () => {
       return {
           msg: 'hello',
           count: 1
       }
   },

// 开启数据缓存
   persist: {
       enabled: true
   }
})

更新数据以后,我们就能在浏览器控制台中看到已经将数据存储到了sessionStorage中

Vue新一代状态管理工具Pinia的具体使用

数据默认是存在sessionStorage中的,还会以store的名称作为key。但是我们可以对其修改,并且还可以只持久化部分state中的属性,代码如下:

import { defineStore } from 'pinia'
import { userStore } from './user'

export const mainStore = defineStore('main', {
   state: () => {
       return {
           msg: 'hello',
           count: 1
       }
   },

// 开启数据缓存
   persist: {
       enabled: true,
       strategies: [
           {
             key: 'mainStore', // 修改存在缓存中的key值
             storage: localStorage,    // 修改存储方式为localStorage
             paths:['msg']  // 只持久化msg,此时刷新页面msg数据会被保留,其他state将会重置
           }
       ]
   }
})

Vue新一代状态管理工具Pinia的具体使用

来源:https://juejin.cn/post/7119832691339444255

标签:Vue,状态管理工具,Pinia
0
投稿

猜你喜欢

  • pytorch:torch.mm()和torch.matmul()的使用

    2022-05-25 21:32:40
  • 面试被问select......for update会锁表还是锁行

    2024-01-17 20:59:17
  • 推荐19个很有用的 JavaScript 库

    2011-05-14 16:33:00
  • Python读取Json字典写入Excel表格的方法

    2021-06-20 06:33:58
  • Python数据分析之 Pandas Dataframe应用自定义

    2023-03-02 09:18:12
  • Sqlserver 常用日期时间函数

    2024-01-16 04:35:44
  • python编程的核心知识点总结

    2023-09-26 21:24:24
  • 一篇文章搞定Mysql日期时间函数

    2024-01-20 19:32:58
  • 深入理解JavaScript系列(38):设计模式之职责链模式详解

    2024-06-05 09:54:55
  • ajax取消挂起请求的处理方法

    2023-11-20 23:41:53
  • 如何实现Django Rest framework版本控制

    2022-10-30 02:29:19
  • 正则化DropPath/drop_path用法示例(Python实现)

    2022-12-01 21:58:34
  • JavaScript 中获取数组最后一个元素方法汇总

    2024-06-07 15:25:25
  • Python3 获取文件属性的方式(时间、大小等)

    2022-05-06 09:13:41
  • Python 模拟动态产生字母验证码图片功能

    2022-02-10 21:03:35
  • 三种不同方式连接MySQL数据库的方法及示例

    2010-06-11 13:37:00
  • 解决win10 vscode 无法激活python 虚拟环境的问题

    2023-10-09 04:23:25
  • MySQL数据库同时查询更新同一张表的方法

    2024-01-22 23:10:38
  • SQL语句中的一些特殊参数如何用变量来代替

    2008-03-14 07:44:00
  • jquery学习笔记之无new构建详解

    2024-04-22 22:20:20
  • asp之家 网络编程 m.aspxhome.com