Skip to content
目录导航

Dealing with Composables

Composables 是利用 Vue Composition API 封装和重用有状态逻辑的函数。 无论您是自己编写、使用 外部库 还是两者兼而有之,您都可以在您的 pinia 商店中充分利用 Composables 的力量。

Option Stores

定义选项存储时,您可以在 state 属性中调用可组合:

ts
export const useAuthStore = defineStore('auth', {
  state: () => ({
    user: useLocalStorage('pinia/auth/login', 'bob'),
  }),
})
1
2
3
4
5

请记住,您只能返回可写状态(例如 ref())。 以下是您可以使用的一些可组合的示例:

以下是一些无法在选项存储中使用的组合示例(但可以与设置存储一起使用):

Setup Stores

另一方面,在定义设置存储时,您几乎可以使用任何可组合的,因为每个属性都被识别为state, action, 或 getter:

ts
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,
  }
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

SSR

在处理 Server Side Rendering 时,您需要注意一些额外的步骤,以便在您的商店中使用可组合组件。

Option Stores 中,您需要定义一个 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) {
    // 在这种情况下,我们可以完全忽略初始状态,因为我们想从浏览器中读取值
    state.user = useLocalStorage('pinia/auth/login', 'bob')
  },
})
1
2
3
4
5
6
7
8
9
10
11
12
13

Setup Stores 中,您需要对不应从初始状态提取的任何状态属性使用名为 skipHydrate() 的帮助程序。 与选项存储不同,设置存储不能只是 skip调用state(),所以我们用skipHydrate()标记不能水合的属性。 请注意,这仅适用于可写反应属性:

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)
  }
})
1
2
3
4
5
6
7
8
9
10
11
12
13