Vue3使用Pinia状态管理,及pinia-plugin-persistedstate持久化插件

2023-09-25 10:36 阅读

在之前的Vue2版本中,官方的状态管理组件为Vuex;而Vue3的官方状态管理组件变更为了Pinia。

适合场景

Vue3中有响应式对象,使用ref或reactive创建的就是响应式对象。但ref和reactive创建的对象一般是组件级别的,即当前组件(或页面)被销毁或不再显示,相应的数据也就全部销毁,无法保留。

如果需要多个组件(页面)共享数据,即全局状态,则需要使用Pinia。

安装Pinia

npm install pinia --save

创建Pinia

在main.ts中加上以下代码:

...
import { createPinia } from 'pinia';
...

const pinia = createPinia();
const app = createApp(App);
...
app.use(pinia);
...

定义Store

一般在/src/stores目录创建stroe。

// appStateStore.ts

export const useAppStateStore = defineStore('ujcmsAppStateStore', {
  state: () => ({
    sidebar: true,
    messageBoxDisplay: false,
    loginBoxDisplay: false,
  }),
  actions: {
    setSidebar(sidebar: boolean) {
      this.sidebar = sidebar;
    },
    closeSidebar() {
      this.sidebar = false;
    },
    toggleSidebar() {
      this.sidebar = !this.sidebar;
    },
    setMessageBoxDisplay(messageBoxDisplay: boolean) {
      this.messageBoxDisplay = messageBoxDisplay;
    },
    setLoginBoxDisplay(loginBoxDisplay: boolean) {
      this.loginBoxDisplay = loginBoxDisplay;
    },
  },
});

使用store

<script setup>
import { useAppStateStore } from '@/stores/appStateStore';

const store = useAppStateStore();
</script>

State

state即是状态。定义和使用都非常简单。直接拿来用即可,而且可以直接修改值。

export const useStore = defineStore('storeId', {
  state: () => ({
    count: 0,
  }),
})
const store = useStore()

store.count++

Getter

getter相当于组件的computed

export const useCounterStore = defineStore('counter', {
  state: () => ({
    count: 0,
  }),
  getters: {
    doubleCount: (state) => state.count * 2,
  },
})
<script setup>
import { useCounterStore } from './counterStore'

const store = useCounterStore()
</script>

<template>
  <p>Double count is {{ store.doubleCount }}</p>
</template>

Actions

actions可以定义一些方法,甚至是异步方法。相当于组件的methods

export const useCounterStore = defineStore('counter', {
  state: () => ({
    count: 0,
  }),
  actions: {
    // since we rely on `this`, we cannot use an arrow function
    increment() {
      this.count++
    },
    randomizeCounter() {
      this.count = Math.round(100 * Math.random())
    },
  },
})
<script setup>
const store = useCounterStore()
// call the action as a method of the store
store.randomizeCounter()
</script>

<template>
  <!-- Even on the template -->
  <button @click="store.randomizeCounter()">Randomize</button>
</template>

pinia-plugin-persistedstate 持久化插件

需要注意的是,Pinia虽然是全局共享的状态,但是一旦页面刷新,所有的数据将全部清除。

如果希望数据在页面刷新之后,依然保持原来的状态,则需要将数据持久化到sessionStorage里面;而如果希望数据在管理浏览器后,再次打开,依然保持原来状态,则需要将数据持久化到localStroage里面。

这两种情况都可以很容易的通过pinia-plugin-persistedstate插件实现。

安装:

npm install pinia-plugin-persistedstate --save

创建。在main.ts中加上以下代码:

...
import { createPinia } from 'pinia';
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate';
...

const pinia = createPinia();
pinia.use(piniaPluginPersistedstate);

const app = createApp(App);
app.use(pinia);
...

定义:

export const useAppStateStore = defineStore('ujcmsAppStateStore', {
  state: () => ({
    sidebar: true,
    messageBoxDisplay: false,
    loginBoxDisplay: false,
  }),
  actions: {
    ...
  },
  persist: {
    // 指定需要持久化的属性。默认持久化所有属性。
    paths: ['sidebar'],
    // 指定持久化的方式。默认localStorage。
    storage: sessionStorage,
  },
});

参考

QQ咨询
电话
微信
微信扫码咨询