]> git.ipfire.org Git - thirdparty/vuejs/pinia.git/commitdiff
docs: better cross usage docs
authorEduardo San Martin Morote <posva13@gmail.com>
Wed, 27 Oct 2021 15:54:53 +0000 (17:54 +0200)
committerEduardo San Martin Morote <posva13@gmail.com>
Wed, 27 Oct 2021 15:54:53 +0000 (17:54 +0200)
packages/docs/cookbook/composing-stores.md
packages/docs/index.md
packages/docs/introduction.md

index 2ddbf27068568651734499e3daa8dee90f2cbde6..0cab027793bd84ce2069dc496cb1608564fe3cd2 100644 (file)
@@ -2,7 +2,45 @@
 
 Composing stores is about having stores that use each other and there is one rule to follow:
 
-If **two or more stores use each other**, you must create a new store in a **separate file** where you import and use all of them.
+If **two or more stores use each other**, they cannot create an infinite loop through _getters_ or _actions_. They cannot **both** directly read each other state in their setup function:
+
+```js
+const useA = defineStore('a', () => {
+  const b = useB()
+
+  // ❌ this is not possible because b also tries to read a.name
+  b.name
+
+  function doSomething() {
+    // ✅ Read b properties in computed or actions
+    const bName = b.name
+    // ...
+  }
+
+  return {
+    name: ref('I am A'),
+  }
+})
+
+const useB = defineStore('b', () => {
+  const a = useA()
+
+  // ❌ this is not possible because a also tries to read a.name
+  a.name
+
+  function doSomething() {
+    // ✅ Read b properties in computed or actions
+    const aName = a.name
+    // ...
+  }
+
+  return {
+    name: ref('I am B'),
+  }
+})
+```
+
+## Nested stores
 
 Note that if one store uses an other store, **there is no need to create a new store in a separate file**, you can directly import it. Think of it as nesting.
 
@@ -33,21 +71,18 @@ export const cartStore = defineStore('cart', {
 
 ## 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:
+You can simply call `useOtherStore()` inside a _getter_:
 
 ```js
 import { defineStore } from 'pinia'
 import { useUserStore } from './user'
-import { useCartStore } from './cart'
 
-export const useSharedStore = defineStore('shared', {
+export const useCartStore = defineStore('cart', {
   getters: {
-    summary() {
+    summary(state) {
       const user = useUserStore()
-      const cart = useCartStore()
 
-      return `Hi ${user.name}, you have ${cart.list.length} items in your cart. It costs ${cart.price}.`
+      return `Hi ${user.name}, you have ${state.list.length} items in your cart. It costs ${state.price}.`
     },
   },
 })
@@ -55,22 +90,21 @@ export const useSharedStore = defineStore('shared', {
 
 ## Shared Actions
 
-When an actions needs to use multiple stores, we do the same, we create a new file with a new store:
+The same applies to _actions_:
 
 ```js
 import { defineStore } from 'pinia'
-import { useUserStore } from './user'
 import { useCartStore } from './cart'
 
-export const useSharedStore = defineStore('shared', {
+export const useCartStore = defineStore('cart', {
   actions: {
     async orderCart() {
       const user = useUserStore()
-      const cart = useCartStore()
 
       try {
-        await apiOrderCart(user.token, cart.items)
-        cart.emptyCart()
+        await apiOrderCart(user.token, this.items)
+        // another action
+        this.emptyCart()
       } catch (err) {
         displayError(err)
       }
index 6f3033879904cd4b9d20e54b553111990eb4977f..9a39a4fe0a680a654b8eb835319d0a68bda20cce 100644 (file)
@@ -5,7 +5,7 @@ actionText: Get Started
 actionLink: /introduction.html
 
 altActionText: Demo
-altActionLink: https://y4dfi.csb.app
+altActionLink: https://stackblitz.com/github/piniajs/example-vue-3-vite
 
 features:
   - title: 💡 Intuitive
index d59708a85effdf4affa6b381d733697b8703a976..733ddbec7689386e8bfa7cd05d33d4155714e236 100644 (file)
@@ -34,8 +34,8 @@ export const useCounterStore = defineStore('counter', {
   actions: {
     increment() {
       this.count++
-    }
-  }
+    },
+  },
 })
 ```
 
@@ -52,7 +52,7 @@ export default {
     // with autocompletion ✨
     counter.$patch({ count: counter.count + 1 })
     // or using an action instead
-    counter.increment();
+    counter.increment()
   },
 }
 ```
@@ -164,8 +164,8 @@ Pinia tries to stay as close as Vuex's philosophy as possible. It was designed t
 
 ### RFCs
 
-While Vuex goes through RFC to gather as much feedback from the community as possible, Pinia doesn't. I test out ideas based on my experience developing applications, reading other people's code and answering questions on Discord.
-This allows me to provide a solution that works, publish often, and make it evolve it while people use it by having breaking changes (very unlikely to have major breaking changes after its first stable release) in major releases if necessary.
+While Vuex goes through RFC to gather as much feedback from the community as possible, Pinia doesn't. I test out ideas based on my experience developing applications, reading other people's code, working for clients who use Pinia, and answering questions on Discord.
+This allows me to provide a solution that works and it adapted to a variety of cases and application sizes. I publish often, and make the library evolve while keeping its core API the same.
 
 ### Comparison with Vuex 3.x/4.x
 
@@ -177,5 +177,5 @@ Pinia API is very different from Vuex ≤4, namely:
 - No need to create custom complex wrappers to support TypeScript, everything is typed and the API is designed in a way to leverage TS type inference as much as possible.
 - No more magic strings to inject, import the functions, call them, enjoy autocompletion!
 - No need to dynamically add stores, they are all dynamic by default and you won't even notice. Note you can still manually use a store to register it whenever you want but because it is automatic you don't need to worry about it.
-- No more nested structuring of _modules_. You can still nest stores implicitly by importing and _using_ a store inside another but Pinia offers a flat structuring by design while still enabling ways of cross composition among stores.
+- No more nested structuring of _modules_. You can still nest stores implicitly by importing and _using_ a store inside another but Pinia offers a flat structuring by design while still enabling ways of cross composition among stores. **You can even have circular dependencies of stores**.
 - No _namespaced modules_. Given the flat architecture of stores, "namespacing" stores is inherent to how they are defined and you could say all stores are namespaced.