Pinia

简介

Pinia 是 Vue 的专属状态管理库,它允许你跨组件或页面共享状态,由 Vue.js团队成员开发。

vuex对比

  1. pinia的模块,不需要嵌套,模块之间可以互相引用,让代码组织更灵活
  2. 搭配 TypeScript 一起使用时有非常可靠的类型推断支持。
  3. 提供了一不仅个更简单的 API,也提供了符合组合式 API 风格的 API

安装

yarn add pinia
# 或者使用 npm
npm install pinia

 完整实例

首先需要在main.js引入

import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'

const pinia = createPinia()
const app = createApp(App)

app.use(pinia)
app.mount('#app')

 定义状态Store

 在深入研究核心概念之前,我们得知道 Store 是用 defineStore() 定义的,它的第一个参数要求是一个独一无二的名字:

import { defineStore } from 'pinia'

// 你可以对 `defineStore()` 的返回值进行任意命名,但最好使用 store 的名字,同时以 `use` 开头且以 `Store` 结尾。(比如 `useUserStore`,`useCartStore`,`useProductStore`)
// 第一个参数是你的应用中 Store 的唯一 ID。
export const useStore = defineStore('main', {
  // 其他配置...
})

这个名字 ,也被用作 id ,是必须传入的, Pinia 将用它来连接 store 和 devtools。为了养成习惯性的用法,将返回的函数命名为 use... 是一个符合组合式函数风格的约定。

defineStore() 的第二个参数可接受两类值:Setup 函数或 Option 对象。

TypeScript

你并不需要做太多努力就能使你的 state 兼容 TS。 Pinia 会自动推断出你的 state 的类型,但在一些情况下,你得用一些方法来帮它一把。

const useStore = defineStore('storeId', {
  state: () => {
    return {
      // 用于初始化空列表
      userList: [] as UserInfo[],
      // 用于尚未加载的数据
      user: null as UserInfo | null,
    }
  },
})

interface UserInfo {
  name: string
  age: number
}

访问 state

默认情况下,你可以通过 store 实例访问 state,直接对其进行读写。

const store = useStore()

store.count++

 重置 state

你可以通过调用 store 的 $reset() 方法将 state 重置为初始值。 

const store = useStore()

store.$reset()

变更 state

 除了用 store.count++ 直接改变 store,你还可以调用 $patch 方法。它允许你用一个 state 的补丁对象在同一时间更改多个属性

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

你也可以通过变更 pinia 实例的 state 来设置整个应用的初始 state。这常用于 SSR 中的激活过程

pinia.state.value = {}

 订阅 state

 类似于 Vuex 的 subscribe 方法,你可以通过 store 的 $subscribe() 方法侦听 state 及其变化。比起普通的 watch(),使用 $subscribe() 的好处是 subscriptions 在 patch 后只触发一次(例如,当使用上面的函数版本时)。

cartStore.$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))
})

 默认情况下,state subscription 会被绑定到添加它们的组件上(如果 store 在组件的 setup() 里面)。这意味着,当该组件被卸载时,它们将被自动删除。如果你想在组件卸载后依旧保留它们,请将 { detached: true } 作为第二个参数,以将 state subscription 从当前组件中分离

export default {
  setup() {
    const someStore = useSomeStore()

    // 在组件被卸载后,该订阅依旧会被保留。
    someStore.$subscribe(callback, { detached: true })

    // ...
  },
}

TIP

你可以在 pinia 实例上侦听整个 state。

watch(
  pinia.state,
  (state) => {
    // 每当状态发生变化时,将整个 state 持久化到本地存储。
    localStorage.setItem('piniaState', JSON.stringify(state))
  },
  { deep: true }
)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值