]> git.ipfire.org Git - thirdparty/vuejs/pinia.git/commitdiff
docs: add composables entry
authorEduardo San Martin Morote <posva13@gmail.com>
Sun, 24 Jul 2022 20:16:07 +0000 (22:16 +0200)
committerEduardo San Martin Morote <posva13@gmail.com>
Sun, 24 Jul 2022 20:16:07 +0000 (22:16 +0200)
packages/docs/.vitepress/config.js
packages/docs/cookbook/composables.md [new file with mode: 0644]
packages/docs/core-concepts/index.md
packages/docs/ssr/advanced.md [deleted file]

index b8c8c81717f5d1290ccf5a521f006d6fe1618eb4..2824f91dc0f0d9e3a710ff91dd7057c2c151ccc6 100644 (file)
@@ -217,6 +217,10 @@ module.exports = {
               text: 'Nuxt.js',
               link: '/ssr/nuxt.html',
             },
+            {
+              text: 'Dealing with composables',
+              link: '/cookbook/composables.html#ssr',
+            },
           ],
         },
         {
@@ -247,6 +251,10 @@ module.exports = {
               text: 'Migration from v0/v1 to v2',
               link: '/cookbook/migration-v1-v2.html',
             },
+            {
+              text: 'Dealing with composables',
+              link: '/cookbook/composables.html',
+            },
           ],
         },
       ],
diff --git a/packages/docs/cookbook/composables.md b/packages/docs/cookbook/composables.md
new file mode 100644 (file)
index 0000000..293b17d
--- /dev/null
@@ -0,0 +1,99 @@
+# Dealing with Composables
+
+[Composables](https://vuejs.org/guide/reusability/composables.html#composables) are functions that leverage Vue Composition API to encapsulate and reuse stateful logic. Whether you write your own, you use [external libraries](https://vueuse.org/) or do both, you can fully use the power of Composables in your pinia stores.
+
+## Option Stores
+
+When defining an option store, you can call a composable inside of the `state` property:
+
+```ts
+export const useAuthStore = defineStore('auth', {
+  state: () => ({
+    user: useLocalStorage('pinia/auth/login', 'bob'),
+  }),
+})
+```
+
+Keep in mind that **you can only return writable state** (e.g. a `ref()`). Here are some examples of composables that you can use:
+
+- [useLocalStorage](https://vueuse.org/core/useLocalStorage/)
+- [useAsyncState](https://vueuse.org/core/useAsyncState/)
+
+Here are some examples of composables that cannot be used in an option stores (but can be used with setup stores):
+
+- [useMediaControls](https://vueuse.org/core/useMediaControls/): exposes functions
+- [useMemoryInfo](https://vueuse.org/core/useMemory/): exposes readonly data
+- [useEyeDropper](https://vueuse.org/core/useEyeDropper/): exposes readonly data and functions
+
+## Setup Stores
+
+On the other hand, when defining a setup store, you can use almost any composable since every property gets discerned into state, action, or getter:
+
+```ts
+import { defineStore, skipHydrate } from 'pinia'
+import { useMediaControls } from '@vueuse/core'
+
+export const useVideoPlayer = defineStore('video', () => {
+  // we won't expose this element directly
+  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,
+  }
+})
+```
+
+## SSR
+
+When dealing with [Server Side Rendering](../ssr/index.md), you need to take care of some extra steps in order to use composables within your stores.
+
+In [Option Stores](#option-stores), you need to define a `hydrate()` function. This function is called when the store is instantiated on the client (the browser) when there is an initial state available at the time the store is created. The reason we need to define this function is because in such scenario, `state()` is not called.
+
+```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')
+  },
+})
+```
+
+In [Setup Stores](#setup-stores), you need to use a helper named `skipHydrate()` on any state property that shouldn't be picked up from the initial state. Differently from option stores, setup stores cannot just _skip calling `state()`_, so we mark properties that cannot be hydrated with `skipHydrate()`. Note that this only applies to writable reactive properties:
+
+```ts
+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(pickedColor), // Ref<string>
+    open, // Function
+    isSupported, // boolean (not even reactive)
+  }
+})
+```
index 3dbf614ef042d5be29c6a3259111571b42e238a8..4750268aef59f52a8939296d30a8af449f14510a 100644 (file)
@@ -64,7 +64,7 @@ In _Setup Stores_:
 - `computed()`s become `getters`
 - `function()`s become `actions`
 
-Setup stores bring a lot more flexibility than [Options Stores](#option-stores) as you can create watchers within a store and freely use any [composable](https://vuejs.org/guide/reusability/composables.html#composables). However, keep in mind that using composables will complexify [SSR](../ssr/advanced.md).
+Setup stores bring a lot more flexibility than [Options Stores](#option-stores) as you can create watchers within a store and freely use any [composable](https://vuejs.org/guide/reusability/composables.html#composables). However, keep in mind that using composables will get more complex [SSR](../ssr/composables.md).
 
 ## What syntax should I pick?
 
diff --git a/packages/docs/ssr/advanced.md b/packages/docs/ssr/advanced.md
deleted file mode 100644 (file)
index b2351ae..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-# Advanced SSR
-
-WIP