vue3 状态管理之 Pinia 的选项式(options API)和组合式 API 的使用方式

Pinia 是什么?

引用官方的一句话:Pinia 是一个符合直觉的 Vue.js 状态管理库

是一个保存状态和业务逻辑的实体,它并不与你的组件树绑定。换句话说,它承载着全局状态。它有点像一个永远存在的组件,每个组件都可以读取和写入它。它有三个概念,state、getter 和 action

简单说几点它的特性:

  1. 它支持 Vue3,同时也支持 Vue2,是 Vuex 的完美过渡替代者
  2. 它极致轻量化,只有 1kb 左右大小
  3. 它类型安全,对 TypeScript 支持更加友好,支持类型自动推断,即使在 JavaScript 中亦可为你提供自动补全功能!(划重点)

Pinia 支持两种写法,跟 Vue3 语法一样,既支持选项式(options)写法,也支持组合式(setup)写法

一、安装 Pinia

在项目中使用 npm 或 yarn 安装 Pinia:
npm install pinia --save

yarn add pinia

二、引入和实例化

在 src 下新建 store 文件,在此文件下创建 inde.js 或者 index.ts
// src/store/index.ts

// 引入createPinia方法从pinia
import { createPinia } from 'pinia'
// 实例化 Pinia
const pinia = createPinia()
// 导出
export default pinia
在 main.ts 中引入并使用 pinia
import pinia from '@/store'

app.use(pinia)

三、Pinia 的定义和使用

选项式写法

与 Vue 的选项式 API 类似,我们也可以传入一个带有 state、actions 与 getters 属性的 Option 对象,与 Vue 的选项式 API 类似,我们也可以传入一个带有 state、actions 与 getters 属性的 Option 对象

import { defineStore } from 'pinia'

interface ICount {
  count: number
}

export const useCounterStore = defineStore('count', {
  state: (): ICount => ({
    count: 0,
  }),
  getters: {
    double(): number {
      return this.count * 2
    },
  },
  actions: {
    increment() {
      this.count++
    },
  },
})

在组件中的使用

<template>
  <el-button @click="countAdd">{{ count }}</el-button>
  <p>doubleCount: {{ doubleCount }}</p>
</template>

<script setup lang="ts">
import { useCounterStore } from '@/store/modules/count'

const counterStore = useCounterStore()
// vite.config.ts 自动导入 Vue 相关函数
const count = computed(() => counterStore.count)
const doubleCount = computed(() => counterStore.double)
const countAdd = () => {
  counterStore.increment()
}
</script>
组合式写法

1、在 Setup Store 中:ref() 就是 state 属性, computed() 就是 getters, function() 就是 actions

2、要让 pinia 正确识别 state,你必须在 setup store 中返回 state 的所有属性。这意味着,你不能在 store 中使用私有属性。不完整返回会影响 SSR ,开发工具和其他插件的正常运行。

3、Setup store 比 Option Store 带来了更多的灵活性,因为你可以在一个 store 内创建侦听器,并自由地使用任何组合式函数。不过,请记住,使用组合式函数会让 SSR 变得更加复杂。

4、Setup store 也可以依赖于全局提供的属性,比如路由。任何应用层面提供的属性都可以在 store 中使用 inject() 访问,就像在组件中一样:

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

export const useCounterStore = defineStore('count', () => {
  const count = ref(0)
  const double = computed(() => {
    return count.value * 2
  })

  function increment() {
    count.value++
  }

  return { count, double, increment }
})

在组件中的使用

<template>
  <el-button @click="countAdd">{{ count }}</el-button>
  <p>doubleCount: {{ double }}</p>
</template>

<script setup lang="ts">
import { useCounterStore } from '@/store/modules/count'
const counterStore = useCounterStore()
// vite.config.ts 自动导入 pinia (storeToRefs) 相关函数
// 为了从 store 中提取属性时保持其响应性,你需要使用 storeToRefs()。它将为每一个响应式属性创建引用。当你只使用 store 的状态而不调用任何 action 时,它会非常有用。请注意,你可以直接从 store 中解构 action,因为它们也被绑定到 store 上
const { count, double } = storeToRefs(counterStore)
const countAdd = () => {
  counterStore.increment()
}
</script>

四、pinia 持久化存储

1、安装持久化插件 pinia-plugin-persistedstate
npm i pinia-plugin-persistedstate

yarn add pinia-plugin-persistedstate
2、将插件添加到 pinia 实例上
import { createPinia } from 'pinia' //引入pinia
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate' //引入持久化插件

const pinia = createPinia() //创建pinia实例
pinia.use(piniaPluginPersistedstate) //将插件添加到 pinia 实例上

export default pinia //导出pinia用于main.js注册
3、默认持久化的配置项
  • 使用 localStorage 进行存储
  • store.$id 作为 storage 默认的 key
  • 使用 JSON.stringify / JSON.parse 进行序列化/反序列化
  • 整个 state 默认将被持久化
4、高级使用:自行配置持久化配置项

key:存储名称。
storage:存储方式。
path:用于指定 state 中哪些数据需要被持久化。[] 表示不持久化任何状态,undefined 或 null 表示持久化整个 state。

import { defineStore } from "pinia"

const useUserInfoStore = defineStore('userInfo', {
  // defineStore('userInfo',{})  userInfo就是这个仓库的名称name
  state: () => ({
    username:'张三',
    age: 18,
    like: '睡觉',
    obj:{ money:10000,friend:66 }
  }),
  getters: {
        ...........
  },
  action:{
    .........
  },
  persist: {
      key: 'piniaStore', //存储名称
      storage: sessionStorage, // 存储方式
      paths: ['username', 'like','obj'], //指定 state 中哪些数据需要被持久化。[] 表示不持久化任何状态,undefined 或 null 表示持久化整个 state
  },
})

export default useUserInfoStore
  • 28
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值