处理可组合函数
可组合函数 是利用 Vue Composition API 来封装和重用有状态逻辑的函数。无论您是编写自己的可组合函数,还是使用 外部库 或者两者兼而有之,您都可以充分利用可组合函数在 Pinia 商店中的强大功能。
选项商店
在定义选项商店时,您可以在 state
属性中调用可组合函数
ts
export const useAuthStore = defineStore('auth', {
state: () => ({
user: useLocalStorage('pinia/auth/login', 'bob'),
}),
})
请记住,**您只能返回可写状态**(例如 ref()
)。以下是一些您可以使用的可组合函数示例
以下是一些在选项商店中无法使用(但可以在设置商店中使用)的可组合函数示例
- useMediaControls: 公开函数
- useMemoryInfo: 公开只读数据
- useEyeDropper: 公开只读数据和函数
设置商店
另一方面,在定义设置商店时,您可以使用几乎任何可组合函数,因为每个属性都会被识别为状态、操作或获取器
ts
import { defineStore, skipHydrate } from 'pinia'
import { useMediaControls } from '@vueuse/core'
export const useVideoPlayer = defineStore('video', () => {
// we won't expose (return) this element directly
const videoElement = ref<HTMLVideoElement>()
const src = ref('/data/video.mp4')
const { playing, volume, currentTime, togglePictureInPicture } =
useMediaControls(videoElement, { src })
function loadVideo(element: HTMLVideoElement, src: string) {
videoElement.value = element
src.value = src
}
return {
src,
playing,
volume,
currentTime,
loadVideo,
togglePictureInPicture,
}
})
警告
与普通状态不同,ref<HTMLVideoElement>()
包含对 DOM 元素的不可序列化引用。这就是我们不直接返回它的原因。由于它是客户端专用状态,我们知道它不会在服务器上设置,并且会在客户端上**始终**以 undefined
开始。
SSR
在处理 服务器端渲染 时,您需要采取一些额外的步骤才能在商店中使用可组合函数。
在 选项商店 中,您需要定义一个 hydrate()
函数。当商店在客户端(浏览器)上实例化时,如果在创建商店时有初始状态可用,则会调用此函数。我们需要定义此函数的原因是,在这种情况下,不会调用 state()
。
ts
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) {
// in this case we can completely ignore the initial state since we
// want to read the value from the browser
state.user = useLocalStorage('pinia/auth/login', 'bob')
},
})
在 设置商店 中,您需要在任何不应从初始状态中获取的 state 属性上使用名为 skipHydrate()
的辅助函数。与选项商店不同,设置商店不能仅仅跳过调用 state()
,因此我们使用 skipHydrate()
标记不能进行水化的属性。请注意,这仅适用于 state 属性
ts
import { defineStore, skipHydrate } from 'pinia'
import { useEyeDropper, useLocalStorage } from '@vueuse/core'
export const useColorStore = defineStore('colors', () => {
const { isSupported, open, sRGBHex } = useEyeDropper()
const lastColor = useLocalStorage('lastColor', sRGBHex)
// ...
return {
lastColor: skipHydrate(lastColor), // Ref<string>
open, // Function
isSupported, // boolean (not even reactive)
}
})