})
```
-Note: the SSR implementation on Pinia might change, but if you intend having SSR on your application, you should avoid using `useStore` functions at the root level of a file to make sure the correct store is retrieved for your currently running application instance. Here is an example:
+## Documentation
-**Avoid doing this**:
-
-```ts
-import { createRouter } from 'vue-router'
-const router = createRouter({
- // ...
-})
-
-// ❌ Depending on where you do this it will fail
-const main = useMainStore()
-
-router.beforeEach((to, from, next) => {
- if (main.isLoggedIn) next()
- else next('/login')
-})
-```
-
-Instead, call `useMainStore()` at the top of `setup`, like `inject` and `provide` in Vue:
-
-```ts
-export default defineComponent({
- setup() {
- // ✅ This will work
- const main = useMainStore()
-
- return {}
- },
-})
-
-// In a different file...
-const pinia = createPinia()
-app.use(pinia)
-
-router.beforeEach((to) => {
- // ✅ This will work (requires pinia param when outside of setup on both
- // Client and Server. See the SSR section below for more information)
- const main = useMainStore(pinia)
-
- if (to.meta.requiresAuth && !main.isLoggedIn) return '/login'
-})
-```
-
-⚠️: Note that if you are developing an SSR application, [you will need to do a bit more](#ssr).
-
-You can access any property defined in `state` and `getters` directly on the store, similar to `data` and `computed` properties in a Vue component.
-
-```ts
-export default defineComponent({
- setup() {
- const main = useMainStore()
- const text = main.name // "eduardo"
- const doubleCount = main.doubleCount // 2
-
- return {
- text, // will always be "eduardo"
- textDynamic: computed(() => main.name), // reactive value
- }
- },
-})
-```
-
-The `main` store in an object wrapped with `reactive`, meaning there is no need to write `.value` after getters but, like `props` in `setup`, we cannot destructure it:
-
-```ts
-export default defineComponent({
- setup() {
- // ❌ This won't work because it breaks reactivity
- // it's the same as destructuring from `props`
- const { name, doubleCount } = useMainStore()
- return { name, doubleCount }
- },
-})
-```
-
-Actions are invoked like methods:
-
-```ts
-export default defineComponent({
- setup() {
- const main = useMainStore()
- // call the action as a method of the store
- main.reset()
-
- return {}
- },
-})
-```
-
-### Mutating the `state`
-
-To mutate the state you can either directly change something:
-
-```ts
-main.counter++
-```
-
-or call the method `$patch` that allows you apply multiple changes at the same time with a partial `state` object:
-
-```ts
-main.$patch({
- counter: -1,
- name: 'Abalam',
-})
-```
-
-The main difference here is that `$patch` allows you to group multiple changes into one single entry in the devtools.
-
-### Replacing the `state`
-
-Simply set your store `$stet` property to a new object:
-
-```ts
-main.$state = { counter: 666, name: 'Paimon' }
-```
-
-### SSR
-
-Creating stores with Pinia should work out of the box for SSR as long as you call your `useStore()` functions at the top of `setup` functions, `getters` and `actions`:
-
-```ts
-export default defineComponent({
- setup() {
- // this works because pinia knows what application is running
- const main = useMainStore()
- return { main }
- },
-})
-```
-
-If you need to use the store somewhere else, you need to pass the `pinia` instance [that was passed to the app](#install-the-plugin) to the `useStore()` function call:
-
-```ts
-const pinia = createPinia()
-const app = createApp(App)
-
-app.use(router)
-app.use(pinia)
-
-router.beforeEach((to) => {
- // ✅ This will work make sure the correct store is used for the current running app
- const main = useMainStore(pinia)
-
- if (to.meta.requiresAuth && !main.isLoggedIn) return '/login'
-})
-```
-
-To hydrate the initial state, you need to make sure the rootState is included somewhere in the HTML for Pinia to pick it up later on:
-
-```js
-import { createPinia } from 'pinia'
-// retrieve the rootState server side
-const pinia = createPinia()
-const app = createApp(App)
-app.use(router)
-app.use(pinia)
-
-// after rendering the page, the root state is build and can be read
-// serialize, escape (VERY important if the content of the state can be changed
-// by the user, which is almost always the case), and place it somewhere on
-// the page, for example, as a global variable. Note you need to use your own
-// `escapeHTML()` function or use an existing package
-escapeHTML(JSON.stringify(pinia.state.value))
-```
-
-On client side, you must hydrate pinia's state before calling any `useStore()` function. For example, if we serialize the state into a `<script>` tag to make it accessible globally on client side through `window.__pinia`, we can write this:
-
-```js
-const pinia = createPinia()
-const app = createApp(App)
-app.use(pinia)
-
-// must be set by the user
-if (isClient) {
- pinia.state.value = JSON.parse(window.__pinia)
-}
-```
-
-### Composing Stores
-
-Composing stores may look hard at first glance but there is only one rule to follow really:
-
-If **multiple stores use each other** or you need to use **multiple stores** at the same time, you must create a **separate file** where you import all of them.
-
-If one store uses an other store, there is no need to create a new file, you can directly import it. Think of it as nesting.
-
-You can call `useOtherStore()` at the top of any getter an action:
-
-```ts
-import { useUserStore } from './user'
-
-export const cartStore = defineStore({
- id: 'cart',
- getters: {
- // ... other getters
- summary() {
- const user = useUserStore()
-
- return `Hi ${user.name}, you have ${this.list.length} items in your cart. It costs ${this.price}.`
- },
- },
-
- actions: {
- purchase() {
- const user = useUserStore()
-
- return apiPurchase(user.id, this.list)
- },
- },
-})
-```
-
-#### Shared Getters
-
-If you need to compute a value based on the `state` and/or `getters` of multiple stores, you may be able to import all the stores but one into the remaining store, but depending on how your stores are used across your application, **this would hurt your code splitting** because importing the store that imports all others stores, would result in **one single big chunk** with all of your stores.
-To prevent this, **we follow the rule above** and we create a new file with a new store:
-
-```ts
-import { defineStore } from 'pinia'
-import { useUserStore } from './user'
-import { useCartStore } from './cart'
-
-export const useSharedStore = defineStore({
- id: 'shared',
- getters: {
- summary() {
- const user = useUserStore()
- const cart = useCartStore()
-
- return `Hi ${user.name}, you have ${cart.list.length} items in your cart. It costs ${cart.price}.`
- },
- },
-})
-```
-
-#### Shared Actions
-
-When an actions needs to use multiple stores, we do the same, we create a new file with a new store:
-
-```ts
-import { defineStore } from 'pinia'
-import { useUserStore } from './user'
-import { useCartStore } from './cart'
-
-export const useSharedStore = defineStore({
- id: 'shared',
- state: () => ({}),
- actions: {
- async orderCart() {
- const user = useUserStore()
- const cart = useCartStore()
-
- try {
- await apiOrderCart(user.token, cart.items)
- cart.emptyCart()
- } catch (err) {
- displayError(err)
- }
- },
- },
-})
-```
-
-## Plugins
-
-TODO: `pinia.use()` + `interface PiniaCustomProperties` for TS
-
-## Subscribing to changes
-
-TODO: `store.$subscribe()`
-
-## Related
+To learn more about Pinia, check [its documentation](https://pinia.esm.dev).
## License