当前位置: 首页 > article >正文

vue中的pinia使用和持久化 - 粘贴即用

学习关键语句:
pinia怎么用

写在前面

pinia 作为 vuex 的替代品好像变得不得不学习了,学起来一用发现 vuex 是什么麻烦的东西,我不认识

这篇文章一共包含的内容有:

  • 安装 pinia
  • 读取数据
  • 修改数据
  • 数据持久化

其中,修改数据只会演示比较常用的两种方式,数据持久化的方法来自满神的这篇文章

文章末尾会有此文章的使用文件链接

开始

安装 pinia

首先我们先创建一个空项目,这里我使用 vite 创建,各位用什么创建都可以

npm create vite

在这里插入图片描述
根据提示打开项目后,我们先将 App.vue 页面清空

App.vue

<template>
  <div>
    123
  </div>
</template>
<script setup lang='ts'>
</script>
<style scoped>
</style>

接下来我们来安装 pinia

npm i pinia

写这篇文章时间的时候 pinia 的版本为 2.0.34 ,不能保证后续版本兼容 注意
在这里插入图片描述

安装完成后,我们在 src 下新建文件夹叫 store,在 store 文件夹下新建文件 index.ts 和 仓库文件 test.ts

在这里插入图片描述

我们将在 index.ts 文件中创建 pinia 实例

index.ts

import { createPinia } from 'pinia'

export const store = createPinia()

我们在 main.ts 中去引入并使用,这里弄得这么麻烦的原因是接下来还要进行持久化操作

main.ts
第 4 行和第 6 行

import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import { store } from './store'

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

接下来我们来制作我们的第一个仓库,喔我早就创建好文件了,这个仓库就叫 test 好了

注意 !在这里我遇到一个问题,导致仓库中的响应式对象只能通过 ref 设置而不能使用 reactive ,使用 reactive 声明的对象在持久化后数据会复原,但我找不到原因,希望有大佬能积极在评论区指点我

我们准备一些数据

test.ts

import { ref } from 'vue'
import { defineStore } from 'pinia'

// defineStore 第一个参数是仓库名,第二个仓库类似于 setup
export const useTestStore = defineStore('test', () => {
    const num = ref<number>(0)
    const name = ref<string>('shaoyahu')
    const user = ref<{ name: string, age: number }>({
        name: '名字叫:',
        age: 18
    })
    const hobby = ref<string[]>(['sing', 'dance'])
    // 修改值的第一种方式 使用仓库的方法
    function addnum() {
        num.value++
    }
    function addhobby() {
        hobby.value.push('rap')
    }

    return {
        num,
        name,
        user,
        hobby,
        addnum,
        addhobby
    }
})

好了,到目前为止,我们的仓库已经准备好了,现在我们去读取数据吧

读取数据

我们将在刚才清空的 App.vue 页面中读取数据

App.vue

<template>
  <div>
    test.num:{{ test.num }}
    <hr>
    test.name:{{ test.name }}
    <hr>
    test.user:{{ test.user }}
    <hr>
    test.hobby:{{ test.hobby }}
    <hr>
    <button @click="test.addnum">num加一</button>
    <button @click="test.addhobby">hobby加一个</button>
  </div>
</template>

<script setup lang='ts'>
import { useTestStore } from './store/test'

const test = useTestStore()
</script>

<style scoped></style>

我们打开浏览器的 vue 工具,里面可以看到 pinia 中的数据
在这里插入图片描述
我们通过对比页面上的数据和 pinia 中的数据,就知道数据已经被我们正常读取到了,接下来我们来试试修改数据

修改数据

修改数据常用的有两种方式,一种是使用仓库中的修改数据的方法,一种是我们直接修改仓库中的数据

使用方法

直接使用仓库中的方法,在上面的文件中,我们点击那两个按钮就可以修改数据了,我们来看一看

在这里插入图片描述

创建函数修改

我们自己创建函数来修改仓库中的数据

App.vue

<template>
  <div>
    test.num:{{ test.num }}
    <hr>
    test.name:{{ test.name }}
    <hr>
    test.user:{{ test.user }}
    <hr>
    test.hobby:{{ test.hobby }}
    <hr>
    <button @click="test.addnum">num加一</button>
    <button @click="test.addhobby">hobby加一个</button>
    <button @click="editname">当场改名</button>
    <button @click="change">给user加个名字</button>
    <button @click="delhobby">删除一个hobby</button>
  </div>
</template>

<script setup lang='ts'>
import { useTestStore } from './store/test'

const test = useTestStore()
const editname = () => {
  test.name = '邵雅虎'
}
const change = () => {
  test.user.name += test.name
}
const delhobby = () => {
  test.hobby.pop()
}
</script>

<style scoped></style>

我们加了三个按钮用来修改数据
在这里插入图片描述

ok 这样我们修改数据也获得大成功,不过有一个问题,那就是这样修改的数据在浏览器刷新后就会恢复,所以我们接下来做数据持久化

数据持久化

想想为什么可以做到数据持久化,前端能把数据放哪呢,不就是放在浏览器里嘛,我们将数据存进浏览器的 localStorage 中

我们先在 src 目录下新建文件夹 utils ,并在文件夹下新建文件 storage.ts,我们封装两个方法来存取storage数据

storage.ts

//存缓存中
export const setStorage = (key: string, value: any) => {
    localStorage.setItem(key, JSON.stringify(value))
}
//缓存中读取
export const getStorage = (key: string) => {
    return (localStorage.getItem(key) ? JSON.parse(localStorage.getItem(key) as string) : {})
}

接下来我们回到 store 下的 index.ts 文件中,进行数据持久化修改

index.ts

import { toRaw } from 'vue'
import { createPinia, type PiniaPluginContext } from 'pinia'
import { getStorage, setStorage } from '../utils/storage'

export const store = createPinia()

// 定义一个默认的保存在 localstroge 中的名字
const __piniaKey__: string = 'piniaDefault'
// 制作一个 pinia 插件
const piniaPlugin = (options?: any) => {
  return (context: PiniaPluginContext) => {
    const { store } = context
    // 读取上回存到的数据
    const data = getStorage(`${options?.key ?? __piniaKey__}-${store.$id}`)
    // 仓库中的数据发生改变时触发 $subscribe
    store.$subscribe(() => {
      let o = toRaw(store.$state)
      let obj: any = {}
      for (const key in o) {
        obj[key] = o[key].value
      }
      // 存入最新的数据
      setStorage(`${options?.key ?? __piniaKey__}-${store.$id}`, obj)
    })
    return {
      ...data
    }
  }
}
// 使用插件,不给 key 时则使用默认名字
store.use(piniaPlugin({
  key: 'pinia'
}))

大致的逻辑就是每次数据更新后将新数据存入 localstroge ,每次刷新页面时都会从 localstroge 中读取数据

注意 ! 这里面有一个问题我没解决,就是在仓库中使用 reactive 定义的响应式对象的数据无法持久化,我试了好久,没有改出来,求求大佬捞一捞

结束

这样子一来,pinia 的使用也就非常清楚了,目前来看,确实要比 vuex 要清晰简洁上不少,如果你有什么疑问或者质疑,请在评论区告诉我

文件链接

这个项目我就放在这里了,点击下载就可以尝试了,不需要积分


http://www.kler.cn/a/10289.html

相关文章:

  • 基于OpenCV的自制Python访客识别程序
  • PNG图片批量压缩exe工具+功能纯净+不改变原始尺寸
  • 【数据结构与算法】第12课—数据结构之归并排序
  • 基于微信小程序的乡村研学游平台设计与实现,LW+源码+讲解
  • HTTP常见的请求头有哪些?都有什么作用?在 Web 应用中使用这些请求头?
  • Spring Boot 2.x 和 Druid 多数据源整合 dm
  • Unity之获取游戏物体对象或组件的几个方法
  • JVM/GC/G1
  • SpringBoot与RabbitMQ 集成以及死信队列,TTL,延迟队列
  • 为什么要创建FAQ?这篇文章告诉你
  • vue3中的全局防抖节流指令
  • Vue学习——【第五弹】
  • 【权限维持】域控后门SSPHOOKDSRMSID万能钥匙
  • 能聊天、会学习,远不是GPT的终局
  • Android—IMS的InputReader
  • 单片机程序是如何运行起来
  • python+vue+ 疫情冷链追溯管理系统
  • 数字中国理念引领国企人力资源数字化转型与实践
  • 2.29、共享内存(2)
  • Springboot整合Quartz实现定时任务数据库动态配置
  • Python数据分析:轻松实现数据处理、分析和可视化的入门教程
  • 代码自动发布系统
  • qt - 隐式共享与d-pointer技术
  • Android 11.0 原生SystemUI下拉通知栏UI背景设置为圆角背景的定制(二)
  • ptuning v2 的 chatglm垂直领域训练记录
  • 银行数字化转型导师坚鹏:金融科技与数字化转型成功案例