]> git.ipfire.org Git - thirdparty/vuejs/pinia.git/commitdiff
docs(zh): sync with English version (#1911)
authorXavi Lee <awxiaoxian2020@163.com>
Thu, 2 Feb 2023 10:14:27 +0000 (18:14 +0800)
committerEduardo San Martin Morote <posva@users.noreply.github.com>
Wed, 15 Feb 2023 09:52:57 +0000 (10:52 +0100)
Co-authored-by: Yoshi Otobe <38850403+yoshiotobe@users.noreply.github.com>
Co-authored-by: Eduardo San Martin Morote <posva13@gmail.com>
Co-authored-by: 林洵锋 <linxunfeng@yeah.net>
Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com>
13 files changed:
packages/docs/.vitepress/config/zh.ts
packages/docs/zh/api/interfaces/pinia._StoreOnActionListenerContext.md
packages/docs/zh/api/modules/pinia.md
packages/docs/zh/cookbook/migration-v1-v2.md
packages/docs/zh/core-concepts/actions.md
packages/docs/zh/core-concepts/getters.md
packages/docs/zh/core-concepts/index.md
packages/docs/zh/core-concepts/plugins.md
packages/docs/zh/core-concepts/state.md
packages/docs/zh/getting-started.md
packages/docs/zh/introduction.md
packages/docs/zh/ssr/index.md
packages/docs/zh/ssr/nuxt.md

index 60b62f8869b0cde2645036b6cc20d412ed53b5f5..09401268ce4552e4637e936294386666695f3003 100644 (file)
@@ -22,7 +22,9 @@ export const zhConfig: LocaleSpecificConfig<DefaultTheme.Config> = {
       text: '对本页提出修改建议',
     },
 
-    outlineTitle: '本页内容',
+    outline: {
+      label: '本页内容'
+    },
 
     nav: [
       // { text: 'Config', link: '/config/' },
index 6024195456d866a1fde695a8e98dbfc0f05aff54..bc4eeeb125f1c1cb66a967f1104c674e3544c9c4 100644 (file)
@@ -35,7 +35,7 @@ sidebarDepth: 3
 action 执行完的钩子。
 它接收 action 的返回值,如果是 Promise,它将被自动解包。
 
-##### 参数{#parameters}
+##### 参数 %{#parameters}%
 
 | 名称 | 类型 |
 | :------ | :------ |
index 9f95cc4807e17a40f8afe86df7e48e17f2a2d224..eafecd4e021051b4bcbb2f8ebf11cf1b4b3f55c3 100644 (file)
@@ -186,7 +186,7 @@ ___
 | :------ |
 | `S` |
 
-#### 类型声明{#type-declaration}
+#### 类型声明 %{#type-declaration}%
 
 ▸ (`mutation`, `state`): `void`
 
@@ -285,7 +285,7 @@ ___
 
 ___
 
-### \_ExtractGettersFromSetupStore{#extractgettersfromsetupstore}
+### \_ExtractGettersFromSetupStore %{#extractgettersfromsetupstore}%
 
 Ƭ **\_ExtractGettersFromSetupStore**<`SS`\>: `SS` extends `undefined` \| `void` ? {} : [`_ExtractGettersFromSetupStore_Keys`](pinia.md#_extractgettersfromsetupstore_keys)<`SS`\> extends keyof `SS` ? `Pick`<`SS`, [`_ExtractGettersFromSetupStore_Keys`](pinia.md#_extractgettersfromsetupstore_keys)<`SS`\>\> : `never`
 
@@ -314,7 +314,7 @@ ___
 
 ___
 
-### \_ExtractStateFromSetupStore{#extractstatefromsetupstore}
+### \_ExtractStateFromSetupStore %{#extractstatefromsetupstore}%
 
 Ƭ **\_ExtractStateFromSetupStore**<`SS`\>: `SS` extends `undefined` \| `void` ? {} : [`_ExtractStateFromSetupStore_Keys`](pinia.md#_extractstatefromsetupstore_keys)<`SS`\> extends keyof `SS` ? [`_UnwrapAll`](pinia.md#_unwrapall)<`Pick`<`SS`, [`_ExtractStateFromSetupStore_Keys`](pinia.md#_extractstatefromsetupstore_keys)<`SS`\>\>\> : `never`
 
@@ -328,7 +328,7 @@ ___
 
 ___
 
-### \_ExtractStateFromSetupStore\_Keys{#extractstatefromsetupstore-keys}
+### \_ExtractStateFromSetupStore\_Keys %{#extractstatefromsetupstore-keys}%
 
 Ƭ **\_ExtractStateFromSetupStore\_Keys**<`SS`\>: keyof { [K in keyof SS as SS[K] extends \_Method \| ComputedRef ? never : K]: any }
 
@@ -545,7 +545,7 @@ ___
 | :------ |
 | `SS` |
 
-## 变量{#variables}
+## 变量 %{#variables}%
 
 ### PiniaVuePlugin %{#piniavueplugin}%
 
@@ -1137,7 +1137,7 @@ ___
 默认为`"Store"`。如果你需要使用 TypeScript,
 请确保扩展 MapStoresCustomization 接口。
 
-#### 参数{#parameters}
+#### 参数 %{#parameters}%
 
 | 名称 | 类型 | 描述 |
 | :------ | :------ | :------ |
index 50418e576b17e21c4800c7bce1daf24f3cf3767c..91d6848fa7cefca651314bd45c40e03d9f4ca510 100644 (file)
@@ -36,43 +36,41 @@ yarn add 'pinia@^2.x.x'
 
 添加于 [2.0.0-rc.0](https://github.com/vuejs/pinia/blob/v2/packages/pinia/CHANGELOG.md#200-rc0-2021-07-28)
 
-用 `StoreGeneric` 取代 `GenericStore` 类型的全部用法。这是新的通用 store 类型,应该可以接受任何类型的 store。如果你在写函数时使用 `Store` 类型而不想传递其泛型(例如`Store<Id, State, Getters, Actions>`),你可以使用 `StoreGeneric`,因为没有泛型的 `Store` 类型会创建一个空的 store 类型:
+用 `StoreGeneric` 取代 `GenericStore` 类型的全部用法。这是新的通用 store 类型,应该可以接受任何类型的 store。如果你在写函数时使用 `Store` 类型而不想传递其泛型 (例如`Store<Id, State, Getters, Actions>`),你可以使用 `StoreGeneric`,因为没有泛型的 `Store` 类型会创建一个空的 store 类型:
 
-```diff
--function takeAnyStore(store: Store) {}
-+function takeAnyStore(store: StoreGeneric) {}
-
--function takeAnyStore(store: GenericStore) {}
-+function takeAnyStore(store: StoreGeneric) {}
+```ts
+function takeAnyStore(store: Store) {} // [!code --]
+function takeAnyStore(store: StoreGeneric) {} // [!code ++]
+function takeAnyStore(store: GenericStore) {} // [!code --]
+function takeAnyStore(store: StoreGeneric) {} // [!code ++]
 ```
 
 ## 针对插件的 `DefineStoreOptions` %{#definestoreoptions-for-plugins}%
 
 如果你在用 TypeScript 写插件并扩展了 `DefineStoreOptions` 类型来添加自定义选项,你应该把它改名为 `DefineStoreOptionsBase`。这个类型将同时适用于 setup 和 option store。
 
-```diff
- declare module 'pinia' {
--  export interface DefineStoreOptions<S, Store> {
-+  export interface DefineStoreOptionsBase<S, Store> {
-     debounce?: {
-       [k in keyof StoreActions<Store>]?: number
-     }
-   }
- }
+```ts
+declare module 'pinia' {
+  export interface DefineStoreOptions<S, Store> { // [!code --]
+  export interface DefineStoreOptionsBase<S, Store> { // [!code ++]
+    debounce?: {
+      [k in keyof StoreActions<Store>]?: number
+    }
+  }
+}
 ```
 
 ## `PiniaStorePlugin` 已被重命名 %{#piniastoreplugin-was-renamed}%
 
 类型 `PiniaStorePlugin` 被重新命名为 `PiniaPlugin`。
 
-```diff
--import { PiniaStorePlugin } from 'pinia'
-+import { PiniaPlugin } from 'pinia'
-
--const piniaPlugin: PiniaStorePlugin = () => {
-+const piniaPlugin: PiniaPlugin = () => {
-   // ...
- }
+```ts
+import { PiniaStorePlugin } from 'pinia' // [!code --]
+import { PiniaPlugin } from 'pinia' // [!code ++]
+const piniaPlugin: PiniaStorePlugin = () => { // [!code --]
+const piniaPlugin: PiniaPlugin = () => { // [!code ++]
+  // ...
+}
 ```
 
 **注意这个更新只能在升级到最新的没有弃用的 Pinia 版本后生效**。
@@ -89,7 +87,7 @@ yarn add @vue/composition-api@latest
 
 ## 支持 webpack 4 %{#webpack-4-support}%
 
-如果你使用的是 webpack 4(Vue CLI 使用的是 webpack 4),你可能会遇到这样的错误:
+如果你使用的是 webpack 4 (Vue CLI 使用的是 webpack 4),你可能会遇到这样的错误:
 
 ```
 ERROR  Failed to compile with 18 errors
@@ -146,7 +144,7 @@ Pinia v2 不再劫持 Vue Devtools v5,它需要的是 Vue Devtools v6。可以
 
 如果你正在使用 Nuxt,pinia 现在有了专门的 Nuxt 软件包🎉。请用以下方法安装它:
 
-```shell
+```bash
 npm i @pinia/nuxt
 # 或者使用 yarn
 yarn add @pinia/nuxt
@@ -156,26 +154,26 @@ yarn add @pinia/nuxt
 
 如果你使用 TypeScript,还要调整你的 `nuxt.config.js` 和 `tsconfig.json`:
 
-```diff
- // nuxt.config.js
- module.exports {
-   buildModules: [
-     '@nuxtjs/composition-api/module',
--    'pinia/nuxt',
-+    '@pinia/nuxt',
-   ],
- }
+```js
+// nuxt.config.js
+module.exports {
+  buildModules: [
+    '@nuxtjs/composition-api/module',
+    'pinia/nuxt', // [!code --]
+    '@pinia/nuxt', // [!code ++]
+  ],
+}
 ```
 
-```diff
- // tsconfig.json
- {
-   "types": [
-     // ...
--    "pinia/nuxt/types"
-+    "@pinia/nuxt"
-   ]
- }
+```json
+// tsconfig.json
+{
+  "types": [
+    // ...
+    "pinia/nuxt/types" // [!code --]
+    "@pinia/nuxt" // [!code ++]
+  ]
+}
 ```
 
 [Nuxt 专属章节](../ssr/nuxt.md)也值得一读。
index 855666c4fef337feb25154e5264141021890e1ef..97e5f6f417055db4f314799028cdd81745d5133c 100644 (file)
@@ -23,7 +23,7 @@ export const useStore = defineStore('main', {
 })
 ```
 
-类似 [getter](./getters.md),action 也可通过 `this` 访问**整个 store 实例**,并支持**完整的类型标注(以及自动补全✨)**。**不同的是,`action` 可以是异步的**,你可以在它们里面 `await` 调用任何 API,以及其他 action!下面是一个使用 [Mande](https://github.com/posva/mande) 的例子。请注意,你使用什么库并不重要,只要你得到的是一个`Promise`,你甚至可以(在浏览器中)使用原生 `fetch` 函数:
+类似 [getter](./getters.md),action 也可通过 `this` 访问**整个 store 实例**,并支持**完整的类型标注(以及自动补全✨)**。**不同的是,`action` 可以是异步的**,你可以在它们里面 `await` 调用任何 API,以及其他 action!下面是一个使用 [Mande](https://github.com/posva/mande) 的例子。请注意,你使用什么库并不重要,只要你得到的是一个`Promise`,你甚至可以 (在浏览器中) 使用原生 `fetch` 函数:
 
 ```js
 import { mande } from 'mande'
@@ -53,18 +53,18 @@ export const useUsers = defineStore('users', {
 
 你也完全可以自由地设置任何你想要的参数以及返回任何结果。当调用 action 时,一切类型也都是可以被自动推断出来的。
 
-Action 可以像方法一样被调用:
-
-```js
-export default defineComponent({
-  setup() {
-    const main = useMainStore()
-    // 作为 store 的一个方法调用该 action
-    main.randomizeCounter()
-
-    return {}
-  },
-})
+Action 可以像函数或者通常意义上的方法一样被调用:
+
+```vue
+<script setup>
+const store = useCounterStore()
+// call the action as a method of the store
+store.randomizeCounter()
+</script>
+<template>
+  <!-- Even on the template -->
+  <button @click="store.randomizeCounter()">Randomize</button>
+</template>
 ```
 
 ## 访问其他 store 的 action %{#accessing-other-stores-actions}%
@@ -92,20 +92,6 @@ export const useSettingsStore = defineStore('settings', {
 })
 ```
 
-## 使用 `setup()` 时的用法 %{#usage-with-setup}%
-
-你可以将任何 action 作为 store 的一个方法直接调用:
-
-```js
-export default {
-  setup() {
-    const store = useStore()
-
-    store.randomizeCounter()
-  },
-}
-```
-
 ## 使用选项式 API 的用法 %{#usage-with-the-options-api}%
 
 <VueSchoolLink
@@ -137,13 +123,12 @@ const useCounterStore = defineStore('counter', {
 
 虽然并不是每个开发者都会使用组合式 API,但 `setup()` 钩子依旧可以使 Pinia 在选项式 API 中更易用。并且不需要额外的映射辅助函数!
 
-```js
+```vue
+<script>
 import { useCounterStore } from '../stores/counter'
-
-export default {
+export default defineComponent({
   setup() {
     const counterStore = useCounterStore()
-
     return { counterStore }
   },
   methods: {
@@ -152,7 +137,8 @@ export default {
       console.log('New Count:', this.counterStore.count)
     },
   },
-}
+})
+</script>
 ```
 
 ### 不使用 `setup()` %{#without-setup}%
@@ -219,15 +205,10 @@ unsubscribe()
 
 默认情况下,*action 订阅器*会被绑定到添加它们的组件上(如果 store 在组件的 `setup()` 内)。这意味着,当该组件被卸载时,它们将被自动删除。如果你想在组件卸载后依旧保留它们,请将 `true` 作为第二个参数传递给 *action 订阅器*,以便将其从当前组件中分离:
 
-```js
-export default {
-  setup() {
-    const someStore = useSomeStore()
-
-    // 在组件被卸载后,这个订阅依旧会被保留。
-    someStore.$onAction(callback, true)
-
-    // ...
-  },
-}
+```vue
+<script setup>
+const someStore = useSomeStore()
+// this subscription will be kept even after the component is unmounted
+someStore.$onAction(callback, true)
+</script>
 ```
index 94113f0be5578ee1a3febdc42dee35e74fbabb97..19018cd66bc63ad77e3d46fdb57efe96aaf82298 100644 (file)
@@ -42,19 +42,13 @@ export const useStore = defineStore('main', {
 然后你可以直接访问 store 实例上的 getter 了:
 
 ```vue
+<script setup>
+import { useCounterStore } from './counterStore'
+const store = useCounterStore()
+</script>
 <template>
   <p>Double count is {{ store.doubleCount }}</p>
 </template>
-
-<script>
-export default {
-  setup() {
-    const store = useStore()
-
-    return { store }
-  },
-}
-</script>
 ```
 
 ## 访问其他 getter %{#accessing-other-getters}%
@@ -101,14 +95,12 @@ export const useStore = defineStore('main', {
 并在组件中使用:
 
 ```vue
-<script>
-export default {
-  setup() {
-    const store = useStore()
-
-    return { getUserById: store.getUserById }
-  },
-}
+<script setup>
+import { useUserListStore } from './store'
+const userList = useUserListStore()
+const { getUserById } = storeToRefs(userList)
+// note you will have to use `getUserById.value` to access
+// the function within the <script setup>
 </script>
 
 <template>
@@ -153,15 +145,12 @@ export const useStore = defineStore('main', {
 
 作为 store 的一个属性,你可以直接访问任何 getter(与 state 属性完全一样):
 
-```js
-export default {
-  setup() {
-    const store = useStore()
-
-    store.count = 3
-    store.doubleCount // 6
-  },
-}
+```vue
+<script setup>
+const store = useCounterStore()
+store.count = 3
+store.doubleCount // 6
+</script>
 ```
 
 ## 使用选项式 API 的用法 %{#usage-with-the-options-api}%
@@ -195,10 +184,11 @@ export const useCounterStore = defineStore('counter', {
 
 虽然并不是每个开发者都会使用组合式 API,但 `setup()` 钩子依旧可以使 Pinia 在选项式 API 中更易用。并且不需要额外的映射辅助函数!
 
-```js
+```vue
+<script>
 import { useCounterStore } from '../stores/counter'
 
-export default {
+export default defineComponent({
   setup() {
     const counterStore = useCounterStore()
 
@@ -209,9 +199,12 @@ export default {
       return this.counterStore.doubleCount * 2
     },
   },
-}
+})
+</script>
 ```
 
+这在将组件从选项式 API 迁移到组合式 API 时很有用,但**应该只是一个迁移步骤**,始终尽量不要在同一组件中混合两种 API 样式。
+
 ### 不使用 `setup()` %{#without-setup}%
 
 你可以使用[前一节的 state](./state.md#options-api) 中的 `mapState()` 函数来将其映射为 getters:
index 6ee26c461a5a2a18051f48a1937995e0caa1177e..45efbb10047e0007bc9d1abbd8494403aec87658 100644 (file)
@@ -12,7 +12,7 @@ import { defineStore } from 'pinia'
 
 // 你可以对 `defineStore()` 的返回值进行任意命名,但最好使用 store 的名字,同时以 `use` 开头且以 `Store` 结尾。(比如 `useUserStore`,`useCartStore`,`useProductStore`)
 // 第一个参数是你的应用中 Store 的唯一 ID。
-export const useStore = defineStore('main', {
+export const useAlertsStore = defineStore('alerts', {
   // 其他配置...
 })
 ```
@@ -72,21 +72,14 @@ Setup store 比 [Option Store](#option-stores) 带来了更多的灵活性,因
 
 ## 使用 Store %{#using-the-store}%
 
-虽然我们前面定义了一个 store,但在 `setup()` 调用 `useStore()` 之前,store 实例是不会被创建的:
+虽然我们前面定义了一个 store,但在我们使用 `<script setup>` 调用 `useStore()`(或者使用 `setup()` 函数,**像所有的组件那样**) 之前,store 实例是不会被创建的:
 
-```js
+```vue
+<script setup>
 import { useCounterStore } from '@/stores/counter'
-
-export default {
-  setup() {
-    const store = useCounterStore()
-
-    return {
-      // 为了能在模板中使用它,你可以返回整个 Store 实例。
-      store,
-    }
-  },
-}
+// access the `store` variable anywhere in the component ✨
+const store = useCounterStore()
+</script>
 ```
 
 你可以定义任意多的 store,但为了让使用 pinia 的益处最大化(比如允许构建工具自动进行代码分割以及 TypeScript 推断),**你应该在不同的文件中去定义 store**。
@@ -97,49 +90,34 @@ export default {
 
 请注意,`store` 是一个用 `reactive` 包装的对象,这意味着不需要在 getters 后面写 `.value`,就像 `setup` 中的 `props` 一样,**如果你写了,我们也不能解构它**:
 
-```js
-export default defineComponent({
-  setup() {
-    const store = useCounterStore()
-    // ❌ 这将无法生效,因为它破坏了响应性
-    // 这与从 `props` 中解构是一样的。
-    const { name, doubleCount } = store
-
-    name // "eduardo"
-    doubleCount // 2
-
-    return {
-      // 始终是 "eduardo"
-      name,
-      // 始终是 2
-      doubleCount,
-      // 这个将是响应式的
-      doubleValue: computed(() => store.doubleCount),
-      }
-  },
-})
+```vue
+<script setup>
+const store = useCounterStore()
+// ❌ This won't work because it breaks reactivity
+// it's the same as destructuring from `props`
+const { name, doubleCount } = store // [!code warning]
+name // will always be "Eduardo" // [!code warning]
+doubleCount // will always be 0 // [!code warning]
+setTimeout(() => {
+  store.increment()
+}, 1000)
+// ✅ this one will be reactive
+// 💡 but you could also just use `store.doubleCount` directly
+const doubleValue = computed(() => store.doubleCount)
+</script>
 ```
 
 为了从 store 中提取属性时保持其响应性,你需要使用 `storeToRefs()`。它将为每一个响应式属性创建引用。当你只使用 store 的状态而不调用任何 action 时,它会非常有用。请注意,你可以直接从 store 中解构 action,因为它们也被绑定到 store 上:
 
-```js
+````vue
+<script setup>
 import { storeToRefs } from 'pinia'
-
-export default defineComponent({
-  setup() {
-    const store = useCounterStore()
-    // `name` and `doubleCount` 都是响应式 refs
-    // 这也将为由插件添加的属性创建 refs
-    // 同时会跳过任何 action 或非响应式(非 ref/响应式)属性
-    const { name, doubleCount } = storeToRefs(store)
-    // 名为 increment 的 action 可以直接提取
-    const { increment } = store
-
-    return {
-      name,
-      doubleCount,
-      increment,
-    }
-  },
-})
+const store = useCounterStore()
+// `name` and `doubleCount` are reactive refs
+// This will also extract refs for properties added by plugins
+// but skip any action or non reactive (non ref/reactive) property
+const { name, doubleCount } = storeToRefs(store)
+// the increment action can just be destructured
+const { increment } = store
+</script>
 ```
index bb783af36e610a9610f938efef21eede1f71aaad..6bc1ba4a5b9cd3e9157a467e93646001262de516 100644 (file)
@@ -1,4 +1,4 @@
-# Plugins %{#plugins}%
+# 插件 %{#plugins}%
 
 由于有了底层 API 的支持,Pinia store 现在完全支持扩展。以下是你可以扩展的内容:
 
@@ -15,8 +15,8 @@
 ```js
 import { createPinia } from 'pinia'
 
-// å\9c¨å®\89è£\85æ­¤æ\8f\92ä»¶å\90\8eå\88\9b建ç\9a\84æ¯\8f个 store ä¸­é\83½ä¼\9aæ·»å\8a ä¸\80个å\90\8d为 `secret` ç\9a\84å±\9eæ\80§ã\80\82
-// 插件可以保存在不同的文件中
+// 创建的每个 store 中都会添加一个名为 `secret` 的属性。
+// 在安装此插件后,插件可以保存在不同的文件中
 function SecretPiniaPlugin() {
   return { secret: 'the cake is a lie' }
 }
@@ -278,6 +278,9 @@ declare module 'pinia' {
 
     // 你也可以定义更简单的值
     simpleNumber: number
+
+     // type the router added by the plugin above (#adding-new-external-properties)
+    router: Router
   }
 }
 ```
index 25db826a262070b1b057f25186df4ac3b44c7baa..44ac115be422a0797035fdfc25e2bba60319aa14 100644 (file)
@@ -231,21 +231,16 @@ cartStore.$subscribe((mutation, state) => {
 
 默认情况下,*state subscription* 会被绑定到添加它们的组件上(如果 store 在组件的 `setup()` 里面)。这意味着,当该组件被卸载时,它们将被自动删除。如果你想在组件卸载后依旧保留它们,请将 `{ detached: true }` 作为第二个参数,以将 *state subscription* 从当前组件中*分离*:
 
-```js
-export default {
-  setup() {
-    const someStore = useSomeStore()
-
-    // 在组件被卸载后,该订阅依旧会被保留。
-    someStore.$subscribe(callback, { detached: true })
-
-    // ...
-  },
-}
+```vue
+<script setup>
+const someStore = useSomeStore()
+// this subscription will be kept even after the component is unmounted
+someStore.$subscribe(callback, { detached: true })
+</script>
 ```
 
 :::tip
-你可以在 `pinia` 实例上侦听整个 state。
+ä½ å\8f¯ä»¥å\9c¨ `pinia` å®\9eä¾\8bä¸\8a使ç\94¨ `watch()` å\87½æ\95°ä¾¦å\90¬æ\95´ä¸ª stateã\80\82
 
 ```js
 watch(
index ed4aaef3495851449743b4f26fc333d1cdd0e09c..34038060a3b6dc63a2d95973f964bc30f4d781f6 100644 (file)
@@ -48,7 +48,7 @@ new Vue({
 
 这样才能提供 devtools 的支持。在 Vue 3 中,一些功能仍然不被支持,如 time traveling 和编辑,这是因为 vue-devtools 还没有相关的 API,但 devtools 也有很多针对 Vue 3 的专属功能,而且就开发者的体验来说,Vue 3 整体上要好得多。在 Vue 2 中,Pinia 使用的是 Vuex 的现有接口(因此不能与 Vuex 一起使用)。
 
-## Store 是什么?{#what-is-a-store}
+## Store 是什么?%{#what-is-a-store}%
 
 Store (如 Pinia) 是一个保存状态和业务逻辑的实体,它并不与你的组件树绑定。换句话说,**它承载着全局状态**。它有点像一个永远存在的组件,每个组件都可以读取和写入它。它有**三个概念**,[state](./core-concepts/state.md)、[getter](./core-concepts/getters.md) 和 [action](./core-concepts/actions.md),我们可以假设这些概念相当于组件中的 `data`、 `computed` 和 `methods`。
 
index bac83780ee294a6eab5fc06ec2eb9026991f06d8..bf43e5dd3f42bb0e172cf994f73b91a8060122e2 100644 (file)
@@ -7,7 +7,7 @@
 
 Pinia [起始](https://github.com/vuejs/pinia/commit/06aeef54e2cad66696063c62829dac74e15fd19e)于 2019 年 11 月左右的一次实验,其目的是设计一个拥有[组合式 API](https://github.com/vuejs/composition-api) 的 Vue 状态管理库。从那时起,我们就倾向于同时支持 Vue 2 和 Vue 3,并且不强制要求开发者使用组合式 API,我们的初心至今没有改变。除了**安装**和 **SSR** 两章之外,其余章节中提到的 API 均支持 Vue 2 和 Vue 3。虽然本文档主要是面向 Vue 3 的用户,但在必要时会标注出 Vue 2 的内容,因此 Vue 2 和 Vue 3 的用户都可以阅读本文档。
 
-## 为什么你应该使用 Pinia?{#why-should-i-use-pinia}
+## 为什么你应该使用 Pinia?%{#why-should-i-use-pinia}%
 
 Pinia 是 Vue 的专属状态管理库,它允许你跨组件或页面共享状态。如果你熟悉组合式 API 的话,你可能会认为可以通过一行简单的 `export const state = reactive({})` 来共享一个全局状态。对于单页应用来说确实可以,但如果应用在服务器端渲染,这可能会使你的应用暴露出一些安全漏洞。 而如果使用 Pinia,即使在小型单页应用中,你也可以获得如下功能:
 
@@ -46,23 +46,23 @@ export const useCounterStore = defineStore('counter', {
 
 然后你就可以在一个组件中使用该 store 了:
 
-```js
+```vue
+<script setup>
 import { useCounterStore } from '@/stores/counter'
-
-export default {
-  setup() {
-    const counter = useCounterStore()
-
-    counter.count++
-    // 带有自动补全 ✨
-    counter.$patch({ count: counter.count + 1 })
-    // 或者使用 action 代替
-    counter.increment()
-  },
-}
+const counter = useCounterStore()
+counter.count++
+// with autocompletion ✨
+counter.$patch({ count: counter.count + 1 })
+// or using an action instead
+counter.increment()
+</script>
+<template>
+  <!-- Access the state directly from the store -->
+  <div>Current Count: {{ counter.count }}</div>
+</template>
 ```
 
-为实现更多高级用法,你甚至可以使用一个函数(与组件 `setup()` 类似)来定义一个 Store:
+为实现更多高级用法,你甚至可以使用一个函数 (与组件 `setup()` 类似) 来定义一个 Store:
 
 ```js
 export const useCounterStore = defineStore('counter', () => {
@@ -94,7 +94,7 @@ const useUserStore = defineStore('user', {
   // ...
 })
 
-export default {
+export default defineComponent({
   computed: {
     // 其他计算属性
     // ...
@@ -107,12 +107,12 @@ export default {
     // 允许读取 this.increment()
     ...mapActions(useCounterStore, ['increment']),
   },
-}
+})
 ```
 
 你将会在核心概念部分了解到更多关于每个**映射辅助函数**的信息。
 
-## 为什么取名 *Pinia*?{#why-pinia}
+## 为什么取名 *Pinia*?%{#why-pinia}%
 
 Pinia (发音为 `/piːnjʌ/`,类似英文中的 “peenya”) 是最接近有效包名 piña (西班牙语中的 *pineapple*,即“菠萝”) 的词。 菠萝花实际上是一组各自独立的花朵,它们结合在一起,由此形成一个多重的水果。 与 Store 类似,每一个都是独立诞生的,但最终它们都是相互联系的。 它(菠萝)也是一种原产于南美洲的美味热带水果。
 
index 557ae6e3f982f7082ad116acb5f3fd2ec158f8eb..b9a692a6100a10cea1db1db71845a9838b71018c 100644 (file)
@@ -6,15 +6,12 @@
 
 只要你只在 `setup` 函数、`getter` 和 `action` 的顶部调用你定义的 `useStore()` 函数,那么使用 Pinia 创建 store 对于 SSR 来说应该是开箱即用的:
 
-```js
-export default defineComponent({
-  setup() {
-    // 这样做的原因是 Pinia 知道
-    // `setup()` 中运行的应用是什么
-    const main = useMainStore()
-    return { main }
-  },
-})
+```vue
+<script setup>
+// this works because pinia knows what application is running inside of
+// `setup`
+const main = useMainStore()
+</script>
 ```
 
 ## 在 `setup()` 外部使用 store %{#using-the-store-outside-of-setup}%
index 7fc628232a5e76586b573d187492923af95efb42..13305f7a6e1e9b3a80d3cf6b4fe2c04873a4e711 100644 (file)
@@ -5,11 +5,21 @@
 ## 安装 %{#installation}%
 
 ```bash
-yarn add @pinia/nuxt
+yarn add pinia @pinia/nuxt
 # 或者使用 npm
-npm install @pinia/nuxt
+npm install pinia @pinia/nuxt
 ```
 
+:::tip 
+如果你正在使用 npm,你可能会遇到 *ERESOLVE unable to resolve dependency tree* 错误。如果那样的话,将以下内容添加到 `package.json` 中:
+
+```js
+"overrides": { 
+  "vue": "latest"
+}
+```
+:::
+
 我们提供了一个 *module* 来为你处理一切,你只需要在 `nuxt.config.js` 文件的 `modules` 中添加它。
 
 ```js
@@ -39,6 +49,15 @@ export default {
 }
 ```
 
+与 `onServerPrefetch()` 一样,如果你想在 `asyncData()` 中调用一个存储动作,你不需要做任何特别的事情。
+
+```vue
+<script setup>
+const store = useStore()
+const { data } = await useAsyncData('user', () => store.fetchUser())
+</script>
+```
+
 ## 自动引入 %{#auto-imports}%
 
 默认情况下,`@pinia/nuxt` 会暴露一个自动引入的方法:`usePinia()`,它类似于 `getActivePinia()`,但在 Nuxt 中效果更好。你可以添加自动引入来减轻你的开发工作: