組合式函數(shù)是利用 Vue 組合式 API 來封裝和復(fù)用有狀態(tài)邏輯的函數(shù)。無論你是自己寫,還是使用外部庫,或者兩者都有,你都可以在 pinia store 中充分發(fā)揮組合式函數(shù)的力量。
當(dāng)定義一個 option store 時,你可以在 state
屬性中調(diào)用組合式函數(shù):
export const useAuthStore = defineStore('auth', {
state: () => ({
user: useLocalStorage('pinia/auth/login', 'bob'),
}),
})
請記住,你只能返回可寫的狀態(tài) (例如,一個 ref()
) 。下面是一些可用的組合式函數(shù)的示例:
下面是一些不可在 option store 中使用的組合式函數(shù) (但可在 setup store 中使用) :
另外,當(dāng)定義一個 setup store 時,你幾乎可以使用任何組合式函數(shù),因為每一個屬性都會被辨別為 state 、action 或者 getter:
import { defineStore, skipHydrate } from 'pinia'
import { useMediaControls } from '@vueuse/core'
export const useVideoPlayer = defineStore('video', () => {
// 我們不會直接暴露這個元素
const videoElement = ref<HTMLVideoElement>()
const src = ref('/data/video.mp4')
const { playing, volume, currentTime, togglePictureInPicture } =
useMediaControls(video, { src })
function loadVideo(element: HTMLVideoElement, src: string) {
videoElement.value = element
src.value = src
}
return {
src,
playing,
volume,
currentTime,
loadVideo,
togglePictureInPicture,
}
})
當(dāng)處理服務(wù)端渲染時,你有一些需要額外注意的內(nèi)容,以便在 store 中使用組合式函數(shù)。
在 Option Store 中,你需要定義一個 hydrate()
函數(shù)。當(dāng) store 在客戶端 (瀏覽器) 上被實例化的過程中,創(chuàng)建 store 時有一個可用的初始狀態(tài)時,這個函數(shù)就會被調(diào)用。我們需要定義這個函數(shù)的原因是,在這種情況下,state()
是不會被調(diào)用的。
import { defineStore, skipHydrate } from 'pinia'
import { useLocalStorage } from '@vueuse/core'
export const useAuthStore = defineStore('auth', {
state: () => ({
user: useLocalStorage('pinia/auth/login', 'bob'),
}),
hydrate(state, initialState) {
// 在這種情況下,我們可以完全忽略初始狀態(tài)
// 因為我們想從瀏覽器中讀取數(shù)值。
state.user = useLocalStorage('pinia/auth/login', 'bob')
},
})
在 Setup Store 中,對于任何不應(yīng)該從初始狀態(tài)中接收的 state 屬性 你都需要使用一個名為 skipHydrate()
的輔助函數(shù)。與 option store 不同,setup store 不能直接跳過調(diào)用 state()
,所以我們用 skipHydrate()
標(biāo)記那些不能被激活的屬性。請注意,這只適用于可寫的響應(yīng)式屬性:
import { defineStore, skipHydrate } from 'pinia'
import { useEyeDropper, useLocalStorage } from '@vueuse/core'
const useColorStore = defineStore('colors', () => {
const { isSupported, open, sRGBHex } = useEyeDropper()
const lastColor = useLocalStorage('lastColor', sRGBHex)
// ...
return {
lastColor: skipHydrate(lastColor), // Ref<string>
open, // Function
isSupported, // boolean (非響應(yīng)式)
}
})
更多建議: