Робота з композиційними функціями
Композиційні функції - це функції, які використовують композиційний API Vue для інкапсуляції та повторного використання логіки стану. Незалежно від того, чи пишете ви власну, використовуєте зовнішні бібліотеки, чи робите і те, і інше, ви можете повністю використовувати потужність композиційних функцій у своїх сховищах pinia.
Опційні сховища
Визначаючи опційне сховище, ви можете викликати композиційну функцію всередині властивості state
:
export const useAuthStore = defineStore('auth', { state: () => ({ user: useLocalStorage('pinia/auth/login', 'bob'), }), })
export const useAuthStore = defineStore('auth', { state: () => ({ user: useLocalStorage('pinia/auth/login', 'bob'), }), })
Майте на увазі, що ви можете повернути лише стан, доступний для запису (наприклад, ref()
). Ось кілька прикладів композиційних функцій, які можна використовувати:
Ось кілька прикладів композиційних функцій, які не можна використовувати в опційних сховищах (але можна використовувати з setup сховищами):
- useMediaControls: розкриває функції
- useMemoryInfo: розкриває дані лише для читання
- useEyeDropper: відкриває дані та функції лише для читання
Setup сховища
З іншого боку, при визначенні setup сховища ви можете використовувати майже будь-які композиційні функції, оскільки кожна властивість розпізнається як стан, дія чи гетер:
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(videoElement, { src }) function loadVideo(element: HTMLVideoElement, src: string) { videoElement.value = element src.value = src } return { src, playing, volume, currentTime, loadVideo, togglePictureInPicture, } })
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(videoElement, { src }) function loadVideo(element: HTMLVideoElement, src: string) { videoElement.value = element src.value = src } return { src, playing, volume, currentTime, loadVideo, togglePictureInPicture, } })
SSR
Коли ви маєте справу з Рендерингом на стороні серверу, вам потрібно подбати про деякі додаткові кроки, щоб використовувати композиційні функції у своїх сховищах.
У Опційних сховищах, вам треба визначити функцію hydrate()
. Ця функція викликається, коли екземпляр сховища створюється на клієнті (браузері), коли на момент створення сховища доступний початковий стан. Причина, чому нам потрібно визначити цю функцію, полягає в тому, що в такому сценарії state()
не викликається.
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') }, })
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') }, })
У Setup сховищах, вам потрібно використовувати помічник під назвою skipHydrate()
для будь-якої властивості стану, яку не слід отримувати з початкового стану. На відміну від сховищ параметрів, опційні сховища не можуть просто пропустити виклик state()
, тому ми позначаємо властивості, які не можна гідратувати за допомогою skipHydrate()
. Зверніть увагу, що це стосується лише реактивних властивостей, доступних для запису:
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 (навіть не реактивне) } })
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 (навіть не реактивне) } })