Pinia 的基本使用

在项目中可能会存在多个页面使用的数据是一样的,在不同页面中需要使用同一数据,这时候我们可以使用本地存储我们要使用的数据,在 vue 中我们有更加灵活和方便来处理这个问题。

Pinia 和 vuex 一样都是用于应用状态的管理,可以在不同页中使用同一数据,用来统一维护。

Pinia 有着两种使用的方式 Option Store 和 Setup Store,允许你跨组件或页面共享状态。那么 Pinia,相比于 vue2 使用的 vuex 有什么优点呢?

  • 更加符合 vue3 组合式 api,让代码更加扁平化,对 vue2 也做到很好的支持
  • 抛弃了 mutations 的操作,使用 state,getters,actions就能进行状态管理编写,简化了操作。
  • 能更好的支持 TypeScript 类型编写。

使用命令行安装 npm install pinia ,使用如下

js 复制代码
// main.ts
import { createPinia } from 'pinia'
import { createApp } from 'vue'
import App from './App.vue'

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

OPtion Store

option store 与 Vue2 的选项式 API 类似,可以传入一个带有 state、actions 与 getters 属性的 Option 对象。

  • state 用于放置要共享的数据。
  • actions 可以在其中定义函数用于处理一些复杂的处理,例如异步操作。
  • getters 调用可以获取 state 中的数据,并且可以进一步处理所需要的数据。
js 复制代码
// setting.ts
import { defineStore } from "pinia";

export const useSettingStore = defineStore('setting', {
  state: () => ({
    title: '不知名网站',
    theme: '#409eff'
  }),

  getters: {
    titleDescribe: (state) => `${state.title}是该网页的主题名`,
  },

  actions: {
    // 修改主题色
    changeSettingTheme() {
      this.theme = this.theme == '#30B08F' ? '#409eff' : '#30B08F'
    },
    setTitle(title: string) {
      this.title = title
    }
  }
})

// 使用
// home.vue
<el-button :color="settingStore.theme" @click="changeSetting">{{
  settingStore.titleDescribe
}}</el-button>

import { useSettingStore } from "@/stores/setting";
const settingStore = useSettingStore();
const changeSetting = () => {
  settingStore.changeSettingTheme();
  settingStore.setTitle("稀土掘金");
};

Setup Store

setup store 更符合Vue3 的 Composition api的风格,可以直接结合vue3的API定义状态

  • defineStore 用来定义 store。
  • storeToRefs 当我们定义好状态管理,需要使用 storeToRefs 来获取store中的属性和方法,并且可以保持数据的响应式。
js 复制代码
import { defineStore } from "pinia";
import { ref, computed } from 'vue'

export const useSettingStore = defineStore('setting', ()=> {
  const title = ref('不知名网站')
  const theme = ref('#409eff')

  const titleDescribe = computed(() => `${title.value}是该网页的主题名`)

  function changeSettingTheme() {
    theme.value = theme.value == '#30B08F' ? '#409eff' : '#30B08F'
  }

  function setTitle(e: string) {
    title.value = e
  }
  // 传递的函数要 return 返回出来才可以使用
  return { title, theme, titleDescribe, changeSettingTheme, setTitle }
})

// 使用
// home.vue
<el-button :color="settingStore.theme" @click="changeSetting">{{
  settingStore.titleDescribe
}}</el-button>

import { useSettingStore } from "@/stores/setting";
const settingStore = useSettingStore();
const changeSetting = () => {
  settingStore.changeSettingTheme();
  settingStore.setTitle("稀土掘金");
};

// 另一种使用方法
<el-button :color="theme" @click="changeSetting">{{
  titleDescribe
}}</el-button>

import { storeToRefs } from "pinia";
import { useSettingStore } from "@/stores/setting";
const { title, theme, titleDescribe } = storeToRefs(useSettingStore())
const { changeSettingTheme, setTitle } = useSettingStore()
const changeSetting = () => {
  changeSettingTheme();
  setTitle("稀土掘金");
  console.log(title.value)
};

持久化存储数据

我们在页面中修改了状态数据,当刷新页面时会出现一个问题,状态数据变回初始状态,这个时候我们需要做持久化存储数据处理。

借助 pinia-plugin-persist 插件去完成存储数据,做到刷新页面数据不变化,他提供了简便的使用方式以及灵活的配置方式。

npm i pinia-plugin-persist

js 复制代码
// main.ts
import { createPinia } from 'pinia'
import piniaPersistPlugin from 'pinia-plugin-persist'
const pinia = createPinia()
pinia.use(piniaPersistPlugin)
app.use(pinia)
js 复制代码
import { defineStore } from "pinia"
import { ref } from "vue"

export const usePageMonitorStore = defineStore('monitor', () => {

  const libraryTraceVal = ref<number>(0)
  const libraryTraceTime = ref<string>('')

  const abilityTraceVal = ref<number>(0)
  const abilityTraceTime = ref<string>('')

  return { libraryTraceVal, libraryTraceTime, abilityTraceVal, abilityTraceTime }
},
{
  persist: {
    enabled: true,
    strategies: [
      { 
        // 不设置 key 、paths 默认保存全部数据
        // storage 值可为 localStorage 、sessionStorage
        key: 'libraryTraceVal',
        storage: sessionStorage,
        paths: ["libraryTraceVal"]
      }
    ]
  }
}
)
相关推荐
Dovis(誓平步青云)5 分钟前
拖动关键帧角色就抽动,动画编辑器怎样补齐中间状态
开发语言·前端·javascript·机器学习·编辑器
lpfasd12313 分钟前
pywebview与Electron
前端·javascript·electron
行走的陀螺仪21 分钟前
Claude Code 从入门到实战(一):安装、登录与第一个Vue项目
前端·javascript·vue.js
梦曦i30 分钟前
0.8.2 新增 backFallback 配置,无 tabbar 页返回无忧
前端·uni-app x
Amos_Web35 分钟前
Rspack 源码解析(三十四):rspack_hook 与宏系统如何用过程宏生成异步 Hook 与插件
前端
恋猫de小郭38 分钟前
感人,Flutter 居然有了一个超实用提案,期待落地
android·前端·flutter
wordbaby44 分钟前
为什么 Apifox 能调通,浏览器却报跨域?一次“CORS Error + 403”联调排坑实录
前端
2603_965896621 小时前
JavaScript 原型与原型链
开发语言·前端·javascript
Amos_Web1 小时前
通过 Rspack 源码学 Rust(四):用 `Option<T>` 表达“查询可能没有结果”
前端
朋友圈自动点赞工具1 小时前
Ruby方法查找:对象不存方法
开发语言·前端·ruby·科技资讯