手寫Pinia源碼(上篇)- 了解和使用Pinia

Pinia簡介

Pinia是Vue的專屬狀態庫,不僅提供了一個更簡單的 API,也提供了符合組合式 API 風格的 API,最重要的是,搭配 TypeScript 一起使用時有非??煽康念愋屯茢嘀С?。

Mutation已被棄用 ,只有 state, getteraction ,簡化狀態管理庫。

Pinia官網

Pinia的使用

基本使用

1. 安裝依賴

npm install pinia
# 使用yarn
yarn add pinia
# 使用pnpm
pnpm i pinia

2. 使用Pinia插件

src/main.ts

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')

3. 創建Store

Option Store

src/store/counter.ts

import { defineStore } from 'pinia'

export const useCounterStore = defineStore('counter', {
  state: () => ({
    count: 1
  }),
  getters: {
    doubleCount(): number {
      return this.count * 2
    },
    tripleCount: state => state.count * 3
  },
  actions: {
    increment(payload: number) {
      this.count += payload
    }
  }
})
Setup Store
import { computed, ref } from 'vue'
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', () => {
  const count = ref(0)
  const doubleCount = computed(() => {
    return count.value * 2
  })
  function increment() {
    count.value++
  }
  return { count, doubleCount, increment }
})

Setup Store 中:

  • ref() 就是 state 屬性
  • computed() 就是 getters
  • function() 就是 actions

4. 在組件中使用

src/App.vue

<script setup lang="ts">
import { useCounterStore } from '@/store/counter'
const countStore = useCounterStore()
const handleClick = () => {
  countStore.increment(2)
}
</script>
<template>
  <p>{{ countStore.count }}</p>
  <button @click="handleClick">修改狀態</button>
</template>

修改數據的方法

1. 通過action修改

store定義actions方法

export const useCounterStore = defineStore('counter', {
  state: () => ({
    count: 1
  }),
  actions: {
    increment(payload: number) {
      this.count += payload
    }
  }
})

在組件中調用

import { useCounterStore } from '@/store/counter'
const countStore = useCounterStore()
const handleClick = () => {
  countStore.increment(2)
}

2. 直接修改state中數據的狀態

在組件中調用

import { useCounterStore } from '@/store/counter'
const countStore = useCounterStore()
const handleClick = () => {
  countStore.count += 1
}

3. 使用$patchAPI

$patch可以接受一個對象或函數

import { useCounterStore } from '@/store/counter'
const countStore = useCounterStore()
const handleClick = () => {
  countStore.$patch({ count: 2 })
}
const handleClick2 = () => {
  countStore.$patch(state => (state.count += 2))
}

API

createPinia

創建一個 Pinia 實例,供應用使用。

defineStore

創建一個 useStore 函數,檢索 store 實例。\

屬性:

#id

store 的唯一標識符

#state

Store 的 State。給它賦值可替換整個 state。

方法:

$patch

將一個 state 補丁應用于當前狀態。

// 對象
countStore.$patch({ count: 2 })
// 函數
countStore.$patch(state => (state.count += 2))
$reset

將 store 重設為初始狀態。只在Option Store可用。

$subscribe

設置一個回調,當狀態發生變化時被調用。返回刪除偵聽器的函數。

store.$subscribe((storeInfo, state) => {
  console.log(storeInfo, state)
})
$onAction

設置一個回調,當一個 action 即將被調用時,就會被調用。

store.$onAction(({ after, onError }) => {
 // 你可以在這里創建所有鉤子之間的共享變量,
 // 同時設置偵聽器并清理它們。
 after((resolvedValue) => {
   // 可以用來清理副作用 
   // `resolvedValue` 是 action 返回的值,
   // 如果是一個 Promise,它將是已經 resolved 的值
 })
 onError((error) => {
   // 可以用于向上傳遞錯誤
 })
})

手寫Pinia源碼(下篇)- 實現Pinia

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容