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

vue状态管理器pinia、pinia-plugin-persist持久化储存

vue状态管理器pinia、pinia-plugin-persist持久化储存

          • 一、简介
          • 二、配置状态管理器,需安装pinia、pinia-plugin-persist
          • 三、定义store:defineStore
          • 五、pinia中的Getter
          • 六、pinia中的Action
          • 七、pinia-plugin-persist持久化储存配置

一、简介

Pinia 是一个基于 Vue 3 的状态管理库,旨在简化和优化 Vue 应用程序的状态管理。它提供了一种简单且强大的方式来管理应用程序的状态,并且与 Vue 3 的响应性系统紧密集成。
以下是 Pinia 的一些特点和优势:
1.基于 Vue 3:Pinia 是专为 Vue 3 设计的状态管理库,充分利用了 Vue 3 的 Composition API 和响应性系统。
2.类型安全:Pinia 支持 TypeScript,并且在状态管理过程中提供了类型检查和推断,帮助开发者避免潜在的类型错误。
3.简单易用:Pinia 的 API 设计简洁清晰,使得状态管理变得简单且易于理解,同时提供了强大的功能。
4.零依赖:Pinia 本身没有任何依赖,因此可以轻松集成到现有的 Vue 3 项目中。
5.插件化:Pinia 支持插件系统,可以轻松扩展和定制状态管理的功能。
6.Devtools 支持:Pinia 与 Vue Devtools 集成良好,可以方便地在开发过程中调试和监控状态的变化。

二、配置状态管理器,需安装pinia、pinia-plugin-persist

1.pinia.js

import { createPinia } from "pinia";
import piniaPersist from "pinia-plugin-persist";

const pinia = createPinia();
pinia.use(piniaPersist); //使用持久化插件

export default pinia;

2.useDemoStore.js

import {defineStore} from "pinia";

const demoStore = defineStore('demoStore', {
    state: () => ({
        userId: '213213',
        userName: '张三'
    }),
    actions: {//actions是store的方法methods
        updateState(info){
            this.$state = {
                ...this.$state,
                ...info
            }
        }
    },
    persist: {//pinia持久化配置,默认sessionStorage
        enabled: true
    }
});

export default demoStore

3.mian.js使用pinia插件

import { createApp } from "vue";
import App from "./App.vue";
import pinia from "@store/pinia.js";

const app = createApp(App);

app.use(pinia);


app.mount("#app");

4.使用store

<template>
  <button @click="onUpdateStore">更新store</button>
  <p>{{demoStore.userName}}</p>
</template>
<script setup>
import useDemoStore from "@store/useDemoStore.js";
const demoStore = useDemoStore();
const  onUpdateStore = ()=>{
  demoStore.updateState({userId: 'wqewqe', userName: '李四'})
}
</script>
三、定义store:defineStore

1.Option Store:defineStore(idid,options),options配置如下

  • id:用于在整个应用程序中标识存储的唯一字符串键,等同于参数id,options传id,参数id可不用传
  • state:创建新状态的函数。必须是箭头函数以确保正确的类型。
  • getters:可选的获取器对象,每个获取器函数都有一个state参数
  • actions:可选的操作对象
  • hydrate:允许在 SSR 期间对存储进行水合处理,当在存储定义中使用复杂状态(例如仅客户端引用)时,并且从 pinia.state 复制值不足以满足需求时。
  • options配置除了上述配置,还可配置插件的配置,如:pinia-plugin-persist持久化储存
import {defineStore} from "pinia";

const demoStore = defineStore('demoStore', {
    state: () => ({
        userId: '213213',
        userName: '张三'
    }),
    actions: {//actions是store的方法methods
        updateState(info){
            this.$state = {
                ...this.$state,
                ...info
            }
        }
    },
    persist: {//pinia持久化配置,默认sessionStorage
        enabled: true
    }
});

export default demoStore

2.Setup Store:defineStore(stoireName,setup,options),options配置如下:

  • actions:可选的操作对象
  • options配置除了上述配置,还可配置插件的配置,如:pinia-plugin-persist持久化储存
const demoStore = defineStore('counter', () => {
    const state = ref({
        userId: '213213',
        userName: '张三'
    });
    const updateState = (info) => {
        state.value = {
            ...state.value,
            ...info
        }
    }

    return {state, updateState}
},{
    persist: {//pinia持久化配置,默认sessionStorage
        enabled: true
    }
})

export default demoStore

3.defineStore除了会返回state、getters、actions等配置,还会返回以下属性:

  • store.$id:储存store的key
  • store.$state:state数据
  • store.$reset():重置store
  • store.$patch(state):更新store
  • store.$subscribe((mutation, state)=>{}):订阅store
  • store.$dispose():用于销毁存储实例并清理其内部状态。当你不再需要某个存储实例时,可以调用该方法来手动触发清理操作,以释放资源并避免内存泄漏
  • store.$onAction((store,name,args, after, onError)=>{}, detached):action监听器,当一个 action 即将被调用时,callback会触发,返回一个删除监听器的函数,detached组件销毁时是否保留监听器
    四、pinia中的State
    在 Pinia 中,state 是存储实例中保存数据的部分。它代表存储的状态,可以包含应用程序中需要共享和管理的数据。在定义 Pinia 存储时,可以通过 state 选项指定一个函数,该函数返回存储的初始状态。
    state 函数应该返回一个对象,该对象包含存储实例的初始状态数据。这些数据可以是任何类型,例如基本数据类型、对象、数组等。通过在 state 函数中返回这些数据,Pinia 将使用它们作为存储实例的初始状态,并在需要时对其进行响应式处理,以确保状态的变化能够正确地触发应用程序的重新渲染。
    通过在存储定义中设置 state,可以轻松地定义和管理存储实例的初始状态,从而构建具有响应式状态管理的应用程序。
    1.定义state,为了完整类型推理,推荐使用箭头函数
import { defineStore } from 'pinia'

const useStore = defineStore('storeId', {
  state: () => {
    return {
      // 所有这些属性都将自动推断出它们的类型
      count: 0,
      name: 'Eduardo',
      isAdmin: true,
      items: [],
      hasChanged: true,
    }
  },
})

2.访问 state,响应式访问state可使用storeToRefs,注意:使用storeToRefs时一定要解构,否则使用时,字符串会多出双引号

const store = useStore()

// count是响应式的 ref
// 同时通过插件添加的属性也会被提取为 ref
// 并且会跳过所有的 action 或非响应式 (不是 ref 或 reactive) 的属性
const {count} = storeToRefs(store());

store.count++

3.重置 state

const store = useStore()

store.$reset()

4.变更 state

const store = useStore()

store.$patch({
  count: store.count + 1,
  age: 120,
  name: 'DIO',
})

5.订阅 state

const store = useStore()
store.$subscribe((mutation, state) => {
  // import { MutationType } from 'pinia'
  mutation.type // 'direct' | 'patch object' | 'patch function'
  // 和 cartStore.$id 一样
  mutation.storeId // 'cart'
  // 只有 mutation.type === 'patch object'的情况下才可用
  mutation.payload // 传递给 cartStore.$patch() 的补丁对象。

  // 每当状态发生变化时,将整个 state 持久化到本地存储。
  localStorage.setItem('cart', JSON.stringify(state))
})
五、pinia中的Getter

在 Pinia 中,getter 是一种用于从存储实例中获取数据的方法。Getter 允许你定义一些计算属性,这些属性可以根据存储实例的状态数据进行计算,并返回相应的结果。通过使用 Getter,可以将一些复杂的逻辑封装在存储实例中,以便在需要时轻松获取计算得到的值。
在定义 Pinia 存储时,你可以通过 getters 选项指定一个包含 Getter 函数的对象。每个 Getter 函数都可以访问存储实例的状态数据,并根据需要执行计算。Getter 函数不会直接修改存储的状态,而是用于派生或计算新的数据。
通过使用 Getter,你可以在存储实例中实现一些复杂的数据逻辑,例如对状态数据进行过滤、排序、映射等操作,从而提供更丰富和灵活的数据访问方式。Getter 的值可以通过在组件中访问存储实例的方式来获取,从而实现对计算属性的使用和响应式更新。
1.定义Getter

export const useCounterStore = defineStore('counter', {
  state: () => ({
    count: 0,
  }),
  getters: {
    doubleCount: (state) => state.count * 2,
    doubleCountPlusOne() { ✨
      return this.doubleCount + 1
    },
  },
})

2.getter 传递参数,getter 是计算属性不能传递参数,可以从 getter 返回一个函数,该函数可以接受任意参数

export const useUserListStore = defineStore('userList', {
  getters: {
    getUserById: (state) => {
      return (userId) => state.users.find((user) => user.id === userId)
    },
  },
})

3.访问其他 store 的 getter,直接调用其他store使用getter即可

import { useOtherStore } from './other-store'

export const useStore = defineStore('main', {
  state: () => ({
    count: 0
  }),
  getters: {
    otherGetter(state) {
      const otherStore = useOtherStore()
      return state.localData + otherStore.data
    },
  },
})

六、pinia中的Action

在 Pinia 中,Action 是一种用于执行异步操作或对存储状态进行修改的方法。Actions 允许在存储实例中定义一些操作,这些操作可以触发状态的变化,并且可以包含异步逻辑,如网络请求、定时器等。通过使用 Actions,可以将数据修改逻辑封装在存储实例中,使应用程序的状态管理更加清晰和可维护。
在定义 Pinia 存储时,可以通过 actions 选项指定一个包含 Action 函数的对象。每个 Action 函数可以接受参数,并且通常会执行一些异步操作,如发起网络请求或执行耗时计算。在 Action 函数中,你可以访问存储实例的状态数据,并根据需要修改这些数据。
Actions 可以被组件调用,从而触发相应的操作。在 Action 函数中,可以通过调用 this 对象来访问存储实例的方法和属性,以便在操作中使用存储的状态数据,并在操作完成后更新状态。Actions 的执行是异步的,因此可以处理需要时间的操作,而不会阻塞应用程序的主线程。
通过使用 Actions,你可以将数据修改逻辑和异步操作集中在存储实例中,使得应用程序的状态管理更加模块化和可测试。
1.定义action

export const useCounterStore = defineStore('main', {
  state: () => ({
    count: 0,
  }),
  actions: {
    increment() {
      this.count++
    },
    randomizeCounter() {
      this.count = Math.round(100 * Math.random())
    },
  },
})

2.访问其他 store 的 action,同getter一样直接调用其他store使用action即可

import { useAuthStore } from './auth-store'

export const useSettingsStore = defineStore('settings', {
  state: () => ({
    preferences: null,

  }),
  actions: {
    async fetchUserPreferences() {
      const auth = useAuthStore()
      if (auth.isAuthenticated) {
        this.preferences = await fetchPreferences()
      } else {
        throw new Error('User must be authenticated')
      }
    },
  },
})

3.订阅 action

const unsubscribe = someStore.$onAction(
  ({
    name, // action 名称
    store, // store 实例,类似 `someStore`
    args, // 传递给 action 的参数数组
    after, // 在 action 返回或解决后的钩子
    onError, // action 抛出或拒绝的钩子
  }) => {
    // 为这个特定的 action 调用提供一个共享变量
    const startTime = Date.now()
    // 这将在执行 "store "的 action 之前触发。
    console.log(`Start "${name}" with params [${args.join(', ')}].`)


    // 这将在 action 成功并完全运行后触发。
    // 它等待着任何返回的 promise
    after((result) => {
      console.log(
        `Finished "${name}" after ${
          Date.now() - startTime
        }ms.\nResult: ${result}.`
      )
    })


    // 如果 action 抛出或返回一个拒绝的 promise,这将触发
    onError((error) => {
      console.warn(
        `Failed "${name}" after ${Date.now() - startTime}ms.\nError: ${error}.`
      )
    })
  }
)

// 手动删除监听器
unsubscribe()
七、pinia-plugin-persist持久化储存配置

1.使用持久化存储插件

import { createPinia } from "pinia";
import piniaPersist from "pinia-plugin-persist";

const pinia = createPinia();
pinia.use(piniaPersist); //使用持久化插件

export default pinia;

2.持久化存储配置,defineStore时增加persist配置

import {defineStore} from "pinia";

const demoStore = defineStore('demoStore', {
    state: () => ({
        userId: '213213',
        userName: '张三'
    }),
    persist: {//pinia持久化配置,默认sessionStorage
        enabled: true
    }
});


export default demoStore

3.持久化储存配置项

  • enabled:是否启用持久化村村
  • strategies:配置策略
    4.配置策略之自定义储存,自定义储存key,并且使用localStorage储存
import {defineStore} from "pinia";

const demoStore = defineStore('demoStore', {
    state: () => ({
        userId: '213213',
        userName: '张三'
    }),
    actions: {//actions是store的方法methods
        updateState(info) {
            this.$state = {
                ...this.$state,
                ...info
            }
        }
    },
    persist: {//pinia持久化配置,默认sessionStorage
        enabled: true,
        strategies: [{
            key:'demo',
            storage: localStorage
        }]
    }
});


export default demoStore

5.配置策略之不同的状态使用不同的储存方式,如下代码:userId使用sessionStorage,userName使用localStorage

import {defineStore} from "pinia";

const demoStore = defineStore('demoStore', {
    state: () => ({
        userId: '213213',
        userName: '张三'
    }),
    actions: {//actions是store的方法methods
        updateState(info) {
            this.$state = {
                ...this.$state,
                ...info
            }
        }
    },
    persist: {//pinia持久化配置,默认sessionStorage
        enabled: true,
        strategies: [{
            storage: sessionStorage,
            paths: ['userId']
        }, {
            storage: localStorage,
            paths: ['userName']
        }]
    }
});


export default demoStore

6.配置策略之定制存储

import Cookies from 'js-cookie'

const cookiesStorage = {
  setItem (key, state) {
    return Cookies.set('accessToken', state.accessToken, { expires: 3 })
  },
  getItem (key) {
    return JSON.stringify({
      accessToken: Cookies.getJSON('accessToken'),
    })
  },
}

export const useUserStore = defineStore('storeUser', {
  state () {
    return {
      firstName: 'S',
      lastName: 'L',
      accessToken: 'xxxxxxxxxxxxx',
    }
  },
  persist: {
    enabled: true,
    strategies: [
      {
        storage: cookiesStorage,
        paths: ['accessToken']
      },
    ],
  },
})

相关文章:

  • 鸿蒙Next-集成HmRouter的路由模式
  • Vala编程语言教程-属性
  • 鸿蒙OS 5.0 服务能力框架深入剖析
  • 手机零售行业的 AI 破局与创新降本实践 | OceanBase DB大咖说
  • 《第三次世界大战》第一章:战争的前夜
  • Java StringUtils工具类常用方法详解
  • COMPASS:通过残差强化学习和技能合成实现跨具身移动策略
  • 深入解剖Linux进程:从诞生到调度的核心机制
  • 2.1-WAF\CDN\OSS\反向代理\负载均衡
  • linux 硬盘扩展
  • PHP弱类型全面复盘
  • Java 大视界 -- 基于 Java 的大数据隐私计算在医疗影像数据共享中的实践探索(158)
  • 【MinIO】Bucket的生命周期管理
  • python多态、静态方法和类方法
  • Open webui的使用
  • Docker Compose 启动jar包项目
  • dubbo http流量接入dubbo后端服务
  • GRS认证是什么?GRS认证有什么意义?对企业发展的好处
  • 剑指Offer49 -- DP_贪心
  • 高中数学联赛模拟试题第9套几何题
  • 网站建设应注意什么/做竞价托管的公司
  • 做二手房产网站多少钱/如何做推广最有效果
  • wordpress 中文付费主题/怎么做seo网站关键词优化
  • 163网易免费邮箱登录/长沙网站seo排名
  • 上海软件系统开发公司/武汉seo计费管理
  • 泰安公司做网站/电商培训班一般多少钱一个月