]> git.ipfire.org Git - thirdparty/vuejs/pinia.git/commitdiff
docs: simplify store usage
authorEduardo San Martin Morote <posva13@gmail.com>
Tue, 20 Jul 2021 09:34:16 +0000 (11:34 +0200)
committerEduardo San Martin Morote <posva13@gmail.com>
Tue, 20 Jul 2021 09:34:16 +0000 (11:34 +0200)
Close #563

docs/.vitepress/config.js
docs/core-concepts/index.md
docs/core-concepts/outside-component-usage.md [new file with mode: 0644]
yarn.lock

index 330c21513cde79657a25a2106768b9859d6ec8e8..f2f4076f8e11a762a4b863ec1bae9a06c708ceed 100644 (file)
@@ -121,6 +121,7 @@ module.exports = {
     ['script', {}, darkModeFix],
     ...(isProduction ? productionHead : []),
   ],
+
   themeConfig: {
     repo: 'posva/pinia',
     logo: '/logo.svg',
@@ -191,6 +192,10 @@ module.exports = {
             { text: 'Getters', link: '/core-concepts/getters.html' },
             { text: 'Actions', link: '/core-concepts/actions.html' },
             { text: 'Plugins', link: '/core-concepts/plugins.html' },
+            {
+              text: 'Stores outside of components',
+              link: '/core-concepts/outside-component-usage.html',
+            },
           ],
         },
         {
index fe0c295c4e7f5af9e6096aeaadb63290d93e37ef..96e5855a4ea949029455bc3abff812a574012ff7 100644 (file)
@@ -16,43 +16,30 @@ The `id` is necessary and is used by `pinia` to connect the store to the devtool
 
 ## Using the store
 
-We are _defining_ a store because the store won't be created until `useStore()` is called inside of `setup()`. You can define as many stores as you want and you should define each store in a different file to get the most out of pinia (like automatically allow your bundle to code split).
-
-It's not possible to call `useStore()` outside of a `setup()` function. Here is an example using a store inside of a navigation guard with Vue Router:
+We are _defining_ a store because the store won't be created until `useStore()` is called inside of `setup()`:
 
 ```js
-import { createRouter } from 'vue-router'
-const router = createRouter({
-  // ...
-})
+import { useStore } from '@/stores/counter'
 
-// ❌ Depending on where you do this it will fail
-const store = useStore()
+export default {
+  setup() {
+    const store = useStore()
 
-router.beforeEach((to, from, next) => {
-  if (store.isLoggedIn) next()
-  else next('/login')
-})
+    return {
+      // you can return the whole store instance to use it in the template
+      store,
+    }
+  },
+}
 ```
 
-Instead, make sure to call `useStore()` inside functions that are called after your application is mounted (`app.mount()` or `new Vue()`):
-
-```js
-router.beforeEach((to) => {
-  // ✅ This will work because the router starts its navigation after pinia is installed
-  const store = useStore()
-
-  if (to.meta.requiresAuth && !store.isLoggedIn) return '/login'
-})
-```
+You can define as many stores as you want and **you should define each store in a different file** to get the most out of pinia (like automatically allow your bundle to code split and TypeScript inference).
 
-:::tip
-When dealing with Server Side Rendering, you will have to pass the `pinia` instance to `useStore()`. Read more about this in the [SSR guide](/ssr/index.md).
-:::
+If you are not using `setup` components yet, [you can still use Pinia with _map helpers_](../cookbook/options-api.md).
 
 Once the store is instantiated, you can access any property defined in `state`, `getters`, and `actions` directly on the store. We will see these in detail in the next pages but autocompletion will help you.
 
-`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:
+Note that `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**:
 
 ```js
 export default defineComponent({
diff --git a/docs/core-concepts/outside-component-usage.md b/docs/core-concepts/outside-component-usage.md
new file mode 100644 (file)
index 0000000..0b4fd51
--- /dev/null
@@ -0,0 +1,60 @@
+# Using a store outside of a component
+
+Pinia stores rely on the `pinia` instance to share the same store instance across all calls. Most of the time, this works out of the box by just calling your `useStore()` function. For example, in `setup()`, you don't need to do anything else. But things are a bit different outside of a component.
+Behind the scenes, `useStore()` _injects_ the `pinia` instance you gave to your `app`. This means that if the `pinia` instance cannot be automatically injected, you have to manually provide it to the `useStore()` function.
+You can solve this differently depending on the kind of application you are writing.
+
+## Single Page Applications
+
+If you are not doing any SSR (Server Side Rendering), any call of `useStore()` after installing the pinia plugin with `app.use(pinia)` will work:
+
+```js
+import { useUserStore } from '@/stores/user'
+import { createApp } from 'vue'
+import App from './App.vue'
+
+// ❌  fails because it's called before the pinia is created
+const userStore = useUserStore()
+
+const pinia = createPinia()
+const app = createApp(App)
+app.use(pinia)
+
+// ✅ works because the pinia instance is now active
+const userStore = useUserStore()
+```
+
+The easiest way to ensure this is always applied is to _defer_ calls of `useStore()` by placing them inside functions that will always run after pinia is installed.
+
+Let's take a look at this example of using a store inside of a navigation guard with Vue Router:
+
+```js
+import { createRouter } from 'vue-router'
+const router = createRouter({
+  // ...
+})
+
+// ❌ Depending on the order of imports this will fail
+const store = useStore()
+
+router.beforeEach((to, from, next) => {
+  // we wanted to use the store here
+  if (store.isLoggedIn) next()
+  else next('/login')
+})
+
+router.beforeEach((to) => {
+  // ✅ This will work because the router starts its navigation after
+  // the router is installed and pinia will be installed too
+  const store = useStore()
+
+  if (to.meta.requiresAuth && !store.isLoggedIn) return '/login'
+})
+```
+
+## SSR Apps
+
+When dealing with Server Side Rendering, you will have to pass the `pinia` instance to `useStore()`. This prevents pinia from sharing global state between different application instances.
+
+There is a whole section dedicated to it in the [SSR guide](/ssr/index.md), this is just a short explanation:
+
index 883a973a55c08561d5d26c7410d4b6a56b48d4dd..f8e1fc795171b6367fe6de3f91636efe3f3c4cb8 100644 (file)
--- a/yarn.lock
+++ b/yarn.lock
@@ -2266,9 +2266,9 @@ dot-prop@^5.1.0:
     is-obj "^2.0.0"
 
 electron-to-chromium@^1.3.723:
-  version "1.3.779"
-  resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.779.tgz#de55492a756deec63424f89fbe62aec9776f0e6d"
-  integrity sha512-nreave0y/1Qhmo8XtO6C/LpawNyC6U26+q7d814/e+tIqUK073pM+4xW7WUXyqCRa5K4wdxHmNMBAi8ap9nEew==
+  version "1.3.780"
+  resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.780.tgz#f946e10dc0005a3b59b9afa2d2c92f5c421f7fc5"
+  integrity sha512-2KQ9OYm9WMUNpAPA/4aerURl3hwRc9tNlpsiEj3Y8Gf7LVf26NzyLIX2v0hSagQwrS9+cWab+28A2GPKDoVNRA==
 
 emittery@^0.7.1:
   version "0.7.2"