[{"data":1,"prerenderedAt":3640},["ShallowReactive",2],{"page-\u002Fvue\u002Fpinia":3},{"id":4,"title":5,"body":6,"description":3633,"extension":3634,"meta":3635,"navigation":827,"path":3636,"seo":3637,"stem":3638,"__hash__":3639},"content\u002FVue\u002FPinia.md","Pinia",{"type":7,"value":8,"toc":3607},"minimark",[9,25,32,37,80,84,89,100,104,111,117,121,128,134,138,141,147,151,160,183,187,213,217,220,380,383,386,393,396,399,405,408,412,415,421,424,427,430,436,439,442,452,459,493,500,535,542,554,558,564,567,573,576,583,624,627,633,639,666,672,675,679,685,688,694,700,706,709,712,718,721,727,730,736,739,750,760,779,782,784,798,801,957,960,1250,1253,1256,1410,1413,1510,1513,1533,1597,1612,1688,1699,1702,2090,2093,2121,2124,2130,2146,2171,2174,2177,2230,2240,2332,2341,2347,2361,2364,2457,2467,2557,2566,2571,2660,2665,2754,2767,2773,2776,2778,2788,2828,2846,2936,2939,2953,3008,3026,3044,3047,3172,3192,3195,3198,3204,3207,3210,3219,3352,3373,3384,3387,3397,3459,3462,3497,3500,3509,3567,3570,3595,3603],[10,11,12,13,16,17,20,21,24],"p",{},"​\t",[14,15,5],"strong",{}," 是 Vue 3 官方推荐的状态管理库，它是 ",[14,18,19],{},"Vuex"," 的继任者，专门为 Vue 3 设计。Pinia 提供了一个更加简洁、直观、功能强大的方式来管理和",[14,22,23],{},"共享应用中的状态（数据）","。",[10,26,27,28,31],{},"​\t在 Vue 3 中，Pinia 通过使用 ",[14,29,30],{},"Composition API"," 提供了更灵活的状态管理方式，相比 Vuex，它有一些显著的优势，例如更好的类型推导（支持 TypeScript）、更简洁的 API，以及与 Vue 3 的新特性（如 Vue Router、Vue Devtools 等）更好地兼容。",[33,34,36],"h3",{"id":35},"pinia-的特点","Pinia 的特点：",[38,39,40,47,60,74],"ol",{},[41,42,43,46],"li",{},[14,44,45],{},"简洁易用","： Pinia 提供了更简洁的 API，使得状态管理更加直观，减少了冗余的代码。例如，获取状态、修改状态以及定义 getters 和 actions 都变得非常简单。",[41,48,49,52,53,56,57,24],{},[14,50,51],{},"TypeScript 支持","： Pinia 完美支持 TypeScript，提供了",[14,54,55],{},"类型推导和检查功能","。你可以在开发过程中得到",[14,58,59],{},"更好的类型提示和代码补全",[41,61,62,65,66,69,70,73],{},[14,63,64],{},"支持模块化","： 你可以",[14,67,68],{},"创建多个 store（类似于 Vuex 的模块）","，以便",[14,71,72],{},"组织和管理应用程序的状态","，使得大项目的状态管理更加清晰和易于维护。",[41,75,76,79],{},[14,77,78],{},"与 Vue 3 配合得更好","： Pinia 完全兼容 Vue 3 的 Composition API，充分利用了 Vue 3 的响应式系统，确保状态管理更加高效和灵活。",[33,81,83],{"id":82},"使用-pinia-的示例","使用 Pinia 的示例",[85,86,88],"h4",{"id":87},"安装","安装：",[90,91,96],"pre",{"className":92,"code":94,"language":95},[93],"language-text","npm install pinia\n","text",[97,98,94],"code",{"__ignoreMap":99},"",[85,101,103],{"id":102},"创建-store","创建 Store：",[10,105,106,107,110],{},"首先，我们创建一个 store 来管理应用的状态。例如，定义一个 ",[97,108,109],{},"counterStore"," 来管理计数器状态。",[90,112,115],{"className":113,"code":114,"language":95},[93],"\u002F\u002F stores\u002FcounterStore.ts\nimport { defineStore } from 'pinia';\n\nexport const useCounterStore = defineStore('counter', {\n  state: () => {\n    return {\n      count: 0,\n    };\n  },\n  getters: {\n    \u002F\u002F 计算属性\n    doubleCount: (state) => state.count * 2,\n  },\n  actions: {\n    \u002F\u002F 修改状态的方法\n    increment() {\n      this.count++;\n    },\n    decrement() {\n      this.count--;\n    },\n  },\n});\n",[97,116,114],{"__ignoreMap":99},[85,118,120],{"id":119},"使用-store","使用 Store：",[10,122,123,124,127],{},"在组件中，我们可以通过 ",[97,125,126],{},"useCounterStore"," 来访问和修改 store 的状态。",[90,129,132],{"className":130,"code":131,"language":95},[93],"\u003Ctemplate>\n  \u003Cdiv>\n    \u003Cp>Count: {{ counter.count }}\u003C\u002Fp>\n    \u003Cp>Double Count: {{ counter.doubleCount }}\u003C\u002Fp>\n    \u003Cbutton @click=\"counter.increment\">Increment\u003C\u002Fbutton>\n    \u003Cbutton @click=\"counter.decrement\">Decrement\u003C\u002Fbutton>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\n\u003Cscript setup>\nimport { useCounterStore } from '.\u002Fstores\u002FcounterStore';\n\nconst counter = useCounterStore();\n\u003C\u002Fscript>\n",[97,133,131],{"__ignoreMap":99},[85,135,137],{"id":136},"配置-pinia","配置 Pinia：",[10,139,140],{},"通常，Pinia 需要在应用的根组件中进行配置。",[90,142,145],{"className":143,"code":144,"language":95},[93],"\u002F\u002F main.ts\nimport { createApp } from 'vue';\nimport { createPinia } from 'pinia';\nimport App from '.\u002FApp.vue';\n\nconst app = createApp(App);\napp.use(createPinia());  \u002F\u002F 将 Pinia 添加到 Vue 应用中\napp.mount('#app');\n",[97,146,144],{"__ignoreMap":99},[33,148,150],{"id":149},"什么是状态管理","什么是状态管理？",[10,152,153,156,157,24],{},[14,154,155],{},"状态管理"," 是指管理应用程序中各种数据的流程和方法。在现代前端开发中，尤其是在构建复杂应用时，状态管理显得尤为重要。状态通常指的是应用的变量数据，它们可以影响 UI 渲染和用户交互，",[14,158,159],{},"也就是在组件之间可以共享重要的数据",[161,162,163,169],"ul",{},[41,164,165,168],{},[14,166,167],{},"全局状态管理","：通常指的是将跨多个组件或页面需要共享的数据放到一个中心化的管理位置，比如 Vuex、Pinia、Redux 等工具。这样，你可以在任何需要的地方访问这些共享的状态。",[41,170,171,174,175,178,179,182],{},[14,172,173],{},"局部状态管理","：则是指在某个组件内部管理该组件的局部数据。Vue 的 ",[97,176,177],{},"data"," 和 React 的 ",[97,180,181],{},"useState"," 就是局部状态管理的典型例子。",[33,184,186],{"id":185},"状态管理的意义","状态管理的意义：",[38,188,189,195,201,207],{},[41,190,191,194],{},[14,192,193],{},"数据共享","： 状态管理使得不同组件可以方便地共享数据，避免了组件之间通过 props 传递数据的繁琐过程，尤其是当多个嵌套组件需要同一数据时，中心化的状态管理就显得非常有用。",[41,196,197,200],{},[14,198,199],{},"组件解耦","： 状态管理可以将数据的管理从组件逻辑中分离出来，使得组件更加关注视图的渲染，而不是处理数据和逻辑。这样，代码的结构和维护性会更好。",[41,202,203,206],{},[14,204,205],{},"可预测性","： 状态管理库（如 Pinia）往往提供了明确的规则和约定，保证了数据的流动性和一致性。当所有的数据操作都通过 store 来进行时，整个应用的状态变得更容易追踪和调试。",[41,208,209,212],{},[14,210,211],{},"便于维护","： 随着项目规模的扩大，应用的状态可能变得复杂且难以维护。通过中心化的状态管理，我们可以清晰地看到哪些数据是全局共享的，哪些是局部状态。",[214,215,216],"h2",{"id":216},"使用",[10,218,219],{},"现在先引入pinia创建pinia再安装。",[90,221,225],{"className":222,"code":223,"language":224,"meta":99,"style":99},"language-ts shiki shiki-themes github-light github-dark","import { createApp } from 'vue'\nimport { createPinia } from 'pinia'\nimport App from '.\u002FApp.vue' \u002F\u002F根组件\n\u002F\u002F引入路由器\nimport router from '.\u002Frouter'\n\u002F\u002F创建应用并使用路由器\nconst app = createApp(App)\nconst pinia = createPinia()\napp.use(router)\napp.use(pinia)\napp.mount('#app') \u002F\u002F挂载到页面上\n\n","ts",[97,226,227,247,260,277,283,296,302,322,338,350,360],{"__ignoreMap":99},[228,229,232,236,240,243],"span",{"class":230,"line":231},"line",1,[228,233,235],{"class":234},"szBVR","import",[228,237,239],{"class":238},"sVt8B"," { createApp } ",[228,241,242],{"class":234},"from",[228,244,246],{"class":245},"sZZnC"," 'vue'\n",[228,248,250,252,255,257],{"class":230,"line":249},2,[228,251,235],{"class":234},[228,253,254],{"class":238}," { createPinia } ",[228,256,242],{"class":234},[228,258,259],{"class":245}," 'pinia'\n",[228,261,263,265,268,270,273],{"class":230,"line":262},3,[228,264,235],{"class":234},[228,266,267],{"class":238}," App ",[228,269,242],{"class":234},[228,271,272],{"class":245}," '.\u002FApp.vue'",[228,274,276],{"class":275},"sJ8bj"," \u002F\u002F根组件\n",[228,278,280],{"class":230,"line":279},4,[228,281,282],{"class":275},"\u002F\u002F引入路由器\n",[228,284,286,288,291,293],{"class":230,"line":285},5,[228,287,235],{"class":234},[228,289,290],{"class":238}," router ",[228,292,242],{"class":234},[228,294,295],{"class":245}," '.\u002Frouter'\n",[228,297,299],{"class":230,"line":298},6,[228,300,301],{"class":275},"\u002F\u002F创建应用并使用路由器\n",[228,303,305,308,312,315,319],{"class":230,"line":304},7,[228,306,307],{"class":234},"const",[228,309,311],{"class":310},"sj4cs"," app",[228,313,314],{"class":234}," =",[228,316,318],{"class":317},"sScJk"," createApp",[228,320,321],{"class":238},"(App)\n",[228,323,325,327,330,332,335],{"class":230,"line":324},8,[228,326,307],{"class":234},[228,328,329],{"class":310}," pinia",[228,331,314],{"class":234},[228,333,334],{"class":317}," createPinia",[228,336,337],{"class":238},"()\n",[228,339,341,344,347],{"class":230,"line":340},9,[228,342,343],{"class":238},"app.",[228,345,346],{"class":317},"use",[228,348,349],{"class":238},"(router)\n",[228,351,353,355,357],{"class":230,"line":352},10,[228,354,343],{"class":238},[228,356,346],{"class":317},[228,358,359],{"class":238},"(pinia)\n",[228,361,363,365,368,371,374,377],{"class":230,"line":362},11,[228,364,343],{"class":238},[228,366,367],{"class":317},"mount",[228,369,370],{"class":238},"(",[228,372,373],{"class":245},"'#app'",[228,375,376],{"class":238},") ",[228,378,379],{"class":275},"\u002F\u002F挂载到页面上\n",[10,381,382],{},"这样就可以使用了。",[10,384,385],{},"就可以在开发工具里看见pinia了。",[10,387,388],{},[389,390],"img",{"alt":391,"src":392},"image-20250222150130242",".\u002Fassets\u002Fimage-20250222150130242.png",[33,394,395],{"id":395},"存储和读取数据的方式",[10,397,398],{},"一般情况我们会在\u002Fsrc文件夹里添加一个\u002Fstore的文件夹，然后依照组件的名称去定义.ts的文件，在里面编写存储数据的方式。   state是真正存储数据的地方",[10,400,401],{},[389,402],{"alt":403,"src":404},"image-20250222151025993",".\u002Fassets\u002Fimage-20250222151025993.png",[33,406,407],{"id":407},"修改数据",[85,409,411],{"id":410},"patch方法","￥patch方法",[10,413,414],{},"$patch:",[10,416,417],{},[389,418],{"alt":419,"src":420},"image-20250222152549936",".\u002Fassets\u002Fimage-20250222152549936.png",[10,422,423],{},"批量改变的方式。",[85,425,426],{"id":426},"action方式",[10,428,429],{},"​\tactions里面是放置的动作方法，用于响应组件中的动作。",[10,431,432],{},[389,433],{"alt":434,"src":435},"image-20250222152903004",".\u002Fassets\u002Fimage-20250222152903004.png",[10,437,438],{},"在.ts里修改和编写。",[10,440,441],{},"​\t我有一个疑问，hooks可以把一个组件的数据的处理和方法集成在一起，pinia的写法又可以把数据的存储和处理放在一起，那么在实际的开发，我要怎么权衡这两种方法。",[10,443,444,445,448,449,451],{},"你的问题很有意义，实际上，",[97,446,447],{},"Hooks"," 和 ",[97,450,5],{}," 主要适用于不同的场景，理解它们各自的优势，可以帮助你在开发中作出合理的选择。",[33,453,455,456],{"id":454},"_1-组件状态-vs-全局状态管理","1. ",[14,457,458],{},"组件状态 vs 全局状态管理",[161,460,461,481],{},[41,462,463,465,466,469,470,473,474,476,477,480],{},[14,464,447],{},"：主要用于",[14,467,468],{},"管理组件内部的状态和逻辑","。当你只需要在一个组件内部处理一些数据，并且",[14,471,472],{},"这个数据不会被其他组件共享时","，使用 ",[97,475,181],{},", ",[97,478,479],{},"useEffect"," 等 Hook 来管理局部状态是很简洁且高效的。它的好处是让每个组件保持独立，管理逻辑清晰，不需要考虑全局状态的复杂性。",[41,482,483,485,486,489,490,492],{},[14,484,5],{},"：用于全局状态管理。它通常在应用的各个部分都需要访问和更新相同的数据时使用。例如，用户登录状态、购物车内容等需要在多个页面或者组件之间共享的数据，Pinia 提供了集中式管理和一致性。你将数据的存储和方法都封装在 ",[97,487,488],{},"store"," 中，多个组件可以通过 ",[97,491,5],{}," 来访问和更新这些状态。",[33,494,496,497],{"id":495},"_2-何时使用-hook何时使用-pinia","2. ",[14,498,499],{},"何时使用 Hook，何时使用 Pinia",[161,501,502,513],{},[41,503,504,505],{},"使用 Hooks：\n",[161,506,507,510],{},[41,508,509],{},"适合局部状态：当一个状态只在一个组件内部使用时，不需要依赖于其他组件，使用 Hooks 是最简单和直接的选择。例如，一个表单输入框的状态，或者一个展开\u002F折叠菜单的状态。",[41,511,512],{},"简单逻辑处理：如果一个组件的逻辑简单且不需要跨组件共享数据，直接在组件内部用 Hooks 来处理是非常高效的。",[41,514,515,516],{},"使用 Pinia：\n",[161,517,518,529],{},[41,519,520,521,524,525,528],{},"适合",[14,522,523],{},"全局共享状态","：当",[14,526,527],{},"多个组件需要访问或修改同一份数据时，使用 Pinia 会让数据管理更加集中和清晰","。例如，用户认证信息、购物车数据等，在不同页面之间共享时就很适合使用 Pinia。",[41,530,531,532,534],{},"跨页面状态管理：如果你需要在多个页面之间传递数据，Pinia 的 ",[97,533,488],{}," 可以作为一个单一的数据源，方便进行全局数据管理，避免了通过 props 或 context 进行复杂的传递。",[33,536,538,539],{"id":537},"_3-代码结构和维护性","3. ",[14,540,541],{},"代码结构和维护性",[161,543,544,549],{},[41,545,546,548],{},[14,547,447],{}," 提供了一个非常直观的方式来将组件的状态与逻辑封装在一起，这使得组件更加独立、易于理解和维护。特别是对于小型应用和较少共享状态的场景，使用 Hooks 会更轻便。",[41,550,551,553],{},[14,552,5],{}," 会让你将数据和处理逻辑集中到 store 中，可以帮助你避免在多个组件之间传递复杂的状态，提升维护性。对于中大型项目，Pinia 的结构化管理方式可以显著降低代码的复杂度，尤其是当你的应用需要管理多个全局状态时，Pinia 能够提供更加清晰的代码结构。",[33,555,557],{"id":556},"sotretorefs","sotreToRefs",[10,559,560],{},[389,561],{"alt":562,"src":563},"image-20250222153515839",".\u002Fassets\u002Fimage-20250222153515839.png",[10,565,566],{},"​\t当模板的读取数据的方式过于繁杂的时候，就像上面的h2标签一样，可以使用这个方法。",[10,568,569],{},[389,570],{"alt":571,"src":572},"image-20250222153619571",".\u002Fassets\u002Fimage-20250222153619571.png",[10,574,575],{},"​\t先把sum,school,address等数据从store中拿出来后，还不是响应式数据，因此，需要用toRefs去转化为双向绑定的响应式数据。",[10,577,578],{},[14,579,580],{},[97,581,582],{},"toRefs",[161,584,585,605],{},[41,586,587,590,591,593,594,597,598,601,602,24],{},[14,588,589],{},"作用","：",[97,592,582],{}," 将一个 ",[97,595,596],{},"reactive"," 对象中的",[14,599,600],{},"每个属性转换为响应式","的 ",[97,603,604],{},"ref",[41,606,607,610,611,613,614,617,618,620,621,24],{},[14,608,609],{},"适用场景","：当你需要将 ",[97,612,596],{}," 对象的",[14,615,616],{},"属性单独暴露","为 ",[97,619,604],{},"，并且希望",[14,622,623],{},"这些属性仍然保持响应式时使用",[33,625,626],{"id":626},"getters配置项",[10,628,629],{},[389,630],{"alt":631,"src":632},"image-20250222154248008",".\u002Fassets\u002Fimage-20250222154248008.png",[10,634,635],{},[389,636],{"alt":637,"src":638},"image-20250222154301313",".\u002Fassets\u002Fimage-20250222154301313.png",[10,640,12,641,644,645,647,648,650,651,654,655,658,659,661,662,665],{},[97,642,643],{},"getters"," 是一个用于从 store 中获取状态的计算属性，它们类似于 Vuex 中的 ",[97,646,643],{},"。通过 ",[97,649,643],{},"，你可以在 ",[14,652,653],{},"store 中计算并返回一些派生状态","，而这些状态的",[14,656,657],{},"值是基于 store 中已有的状态来计算","的。",[97,660,643],{}," 使得你可以在",[14,663,664],{},"多个组件中共享计算结果","，而不需要重复计算。",[10,667,668],{},[389,669],{"alt":670,"src":671},"image-20250222154444019",".\u002Fassets\u002Fimage-20250222154444019.png",[10,673,674],{},"一样可以取出来",[33,676,678],{"id":677},"订阅subscribe-监视vuex里数据的变化","订阅$subscribe 监视vuex里数据的变化",[10,680,681],{},[389,682],{"alt":683,"src":684},"image-20250222154733555",".\u002Fassets\u002Fimage-20250222154733555.png",[10,686,687],{},"可以看到在数据变化后：",[10,689,690],{},[389,691],{"alt":692,"src":693},"image-20250222154749466",".\u002Fassets\u002Fimage-20250222154749466.png",[10,695,696,697],{},"看得到事件(events)和关键的state。有些像",[14,698,699],{},"watch",[10,701,702],{},[389,703],{"alt":704,"src":705},"image-20250222154920561",".\u002Fassets\u002Fimage-20250222154920561.png",[10,707,708],{},"可以用这种方式保存在浏览器本地，可以实现刷新不丢失。",[10,710,711],{},"然后可以在sotre里读取本地存取的数值。",[10,713,714],{},[389,715],{"alt":716,"src":717},"image-20250222155048352",".\u002Fassets\u002Fimage-20250222155048352.png",[10,719,720],{},"只是这个不一定取得出来，可能值为null 可以在前面加个断言",[10,722,723],{},[389,724],{"alt":725,"src":726},"image-20250222155226466",".\u002Fassets\u002Fimage-20250222155226466.png",[33,728,729],{"id":729},"store组合式",[10,731,732],{},[389,733],{"alt":734,"src":735},"image-20250222155523132",".\u002Fassets\u002Fimage-20250222155523132.png",[10,737,738],{},"记得把函数和属性交出去。",[10,740,741,742,745,746,749],{},"​\t如果你导出的是一个变量（常量、对象、数组等），你不需要使用 ",[97,743,744],{},"return","，因为 ",[97,747,748],{},"export"," 只是让这个变量可用于其他模块。",[10,751,752,753,756,757,759],{},"​\t如果你导出的是一个",[14,754,755],{},"函数","，那么是否需要 ",[97,758,744],{}," 取决于函数的类型。",[161,761,762,771],{},[41,763,764,767,768,770],{},[14,765,766],{},"普通函数","：如果函数需要返回一个值，你应该使用 ",[97,769,744],{}," 来返回数据。",[41,772,773,776,777,24],{},[14,774,775],{},"没有返回值的函数","：如果函数只是执行某些操作（如修改全局状态或触发副作用），则不需要 ",[97,778,744],{},[214,780,781],{"id":781},"高级用法",[33,783,643],{"id":643},[10,785,786,789,790,793,794,797],{},[14,787,788],{},"Getter 就是 Pinia 里的“计算属性）”","。它的作用是",[14,791,792],{},"基于 state 派生出新的数据","，并且",[14,795,796],{},"自动缓存","，只有依赖的 state 变化时才会重新计算。",[10,799,800],{},"state里面存储的是原始数据，但是展示的时候需要格式化，我们可以用getter中的方式进行格式化：",[90,802,804],{"className":222,"code":803,"language":224,"meta":99,"style":99},"getters: {\n  \u002F\u002F 不用 getter：每次都要写\n  \u002F\u002F 组件里：`${person.age}岁` 到处重复\n\n  \u002F\u002F 用 getter：统一格式化\n  formattedPeople: (state) => {\n    return state.peopleList.map(p => ({\n      ...p,\n      displayName: `${p.name} (${p.age}岁)`,\n      statusLabel: p.status === 'active' ? '✅ 活跃' : '❌ 非活跃',\n    }))\n  },\n}\n",[97,805,806,813,818,823,829,834,854,875,883,915,940,945,951],{"__ignoreMap":99},[228,807,808,810],{"class":230,"line":231},[228,809,643],{"class":317},[228,811,812],{"class":238},": {\n",[228,814,815],{"class":230,"line":249},[228,816,817],{"class":275},"  \u002F\u002F 不用 getter：每次都要写\n",[228,819,820],{"class":230,"line":262},[228,821,822],{"class":275},"  \u002F\u002F 组件里：`${person.age}岁` 到处重复\n",[228,824,825],{"class":230,"line":279},[228,826,828],{"emptyLinePlaceholder":827},true,"\n",[228,830,831],{"class":230,"line":285},[228,832,833],{"class":275},"  \u002F\u002F 用 getter：统一格式化\n",[228,835,836,839,842,846,848,851],{"class":230,"line":298},[228,837,838],{"class":317},"  formattedPeople",[228,840,841],{"class":238},": (",[228,843,845],{"class":844},"s4XuR","state",[228,847,376],{"class":238},[228,849,850],{"class":234},"=>",[228,852,853],{"class":238}," {\n",[228,855,856,859,862,865,867,869,872],{"class":230,"line":304},[228,857,858],{"class":234},"    return",[228,860,861],{"class":238}," state.peopleList.",[228,863,864],{"class":317},"map",[228,866,370],{"class":238},[228,868,10],{"class":844},[228,870,871],{"class":234}," =>",[228,873,874],{"class":238}," ({\n",[228,876,877,880],{"class":230,"line":324},[228,878,879],{"class":234},"      ...",[228,881,882],{"class":238},"p,\n",[228,884,885,888,891,893,896,899,902,904,906,909,912],{"class":230,"line":340},[228,886,887],{"class":238},"      displayName: ",[228,889,890],{"class":245},"`${",[228,892,10],{"class":238},[228,894,895],{"class":245},".",[228,897,898],{"class":238},"name",[228,900,901],{"class":245},"} (${",[228,903,10],{"class":238},[228,905,895],{"class":245},[228,907,908],{"class":238},"age",[228,910,911],{"class":245},"}岁)`",[228,913,914],{"class":238},",\n",[228,916,917,920,923,926,929,932,935,938],{"class":230,"line":352},[228,918,919],{"class":238},"      statusLabel: p.status ",[228,921,922],{"class":234},"===",[228,924,925],{"class":245}," 'active'",[228,927,928],{"class":234}," ?",[228,930,931],{"class":245}," '✅ 活跃'",[228,933,934],{"class":234}," :",[228,936,937],{"class":245}," '❌ 非活跃'",[228,939,914],{"class":238},[228,941,942],{"class":230,"line":362},[228,943,944],{"class":238},"    }))\n",[228,946,948],{"class":230,"line":947},12,[228,949,950],{"class":238},"  },\n",[228,952,954],{"class":230,"line":953},13,[228,955,956],{"class":238},"}\n",[10,958,959],{},"可以根据条件来动态展示数据的不同子集：",[90,961,963],{"className":222,"code":962,"language":224,"meta":99,"style":99},"getters: {\n  \u002F\u002F 根据关键词搜索\n  searchedPeople: (state) => {\n    if (!state.searchKeyword) return state.peopleList\n    return state.peopleList.filter(p =>\n      p.name.includes(state.searchKeyword)\n    )\n  },\n\n  \u002F\u002F 排序\n  sortedByAge: (state) => {\n    return [...state.peopleList].sort((a, b) => a.age - b.age)\n  },\n\n  \u002F\u002F 组合：过滤 + 排序\n  filteredAndSorted: (state) => {\n    let result = state.peopleList\n    \u002F\u002F 先过滤\n    if (state.searchKeyword) {\n      result = result.filter(p => p.name.includes(state.searchKeyword))\n    }\n    \u002F\u002F 再排序\n    return [...result].sort((a, b) => a.age - b.age)\n  },\n}\n",[97,964,965,971,976,991,1010,1026,1037,1042,1046,1050,1055,1070,1110,1114,1119,1125,1141,1155,1161,1169,1196,1202,1208,1240,1245],{"__ignoreMap":99},[228,966,967,969],{"class":230,"line":231},[228,968,643],{"class":317},[228,970,812],{"class":238},[228,972,973],{"class":230,"line":249},[228,974,975],{"class":275},"  \u002F\u002F 根据关键词搜索\n",[228,977,978,981,983,985,987,989],{"class":230,"line":262},[228,979,980],{"class":317},"  searchedPeople",[228,982,841],{"class":238},[228,984,845],{"class":844},[228,986,376],{"class":238},[228,988,850],{"class":234},[228,990,853],{"class":238},[228,992,993,996,999,1002,1005,1007],{"class":230,"line":279},[228,994,995],{"class":234},"    if",[228,997,998],{"class":238}," (",[228,1000,1001],{"class":234},"!",[228,1003,1004],{"class":238},"state.searchKeyword) ",[228,1006,744],{"class":234},[228,1008,1009],{"class":238}," state.peopleList\n",[228,1011,1012,1014,1016,1019,1021,1023],{"class":230,"line":285},[228,1013,858],{"class":234},[228,1015,861],{"class":238},[228,1017,1018],{"class":317},"filter",[228,1020,370],{"class":238},[228,1022,10],{"class":844},[228,1024,1025],{"class":234}," =>\n",[228,1027,1028,1031,1034],{"class":230,"line":298},[228,1029,1030],{"class":238},"      p.name.",[228,1032,1033],{"class":317},"includes",[228,1035,1036],{"class":238},"(state.searchKeyword)\n",[228,1038,1039],{"class":230,"line":304},[228,1040,1041],{"class":238},"    )\n",[228,1043,1044],{"class":230,"line":324},[228,1045,950],{"class":238},[228,1047,1048],{"class":230,"line":340},[228,1049,828],{"emptyLinePlaceholder":827},[228,1051,1052],{"class":230,"line":352},[228,1053,1054],{"class":275},"  \u002F\u002F 排序\n",[228,1056,1057,1060,1062,1064,1066,1068],{"class":230,"line":362},[228,1058,1059],{"class":317},"  sortedByAge",[228,1061,841],{"class":238},[228,1063,845],{"class":844},[228,1065,376],{"class":238},[228,1067,850],{"class":234},[228,1069,853],{"class":238},[228,1071,1072,1074,1077,1080,1083,1086,1089,1092,1094,1097,1099,1101,1104,1107],{"class":230,"line":947},[228,1073,858],{"class":234},[228,1075,1076],{"class":238}," [",[228,1078,1079],{"class":234},"...",[228,1081,1082],{"class":238},"state.peopleList].",[228,1084,1085],{"class":317},"sort",[228,1087,1088],{"class":238},"((",[228,1090,1091],{"class":844},"a",[228,1093,476],{"class":238},[228,1095,1096],{"class":844},"b",[228,1098,376],{"class":238},[228,1100,850],{"class":234},[228,1102,1103],{"class":238}," a.age ",[228,1105,1106],{"class":234},"-",[228,1108,1109],{"class":238}," b.age)\n",[228,1111,1112],{"class":230,"line":953},[228,1113,950],{"class":238},[228,1115,1117],{"class":230,"line":1116},14,[228,1118,828],{"emptyLinePlaceholder":827},[228,1120,1122],{"class":230,"line":1121},15,[228,1123,1124],{"class":275},"  \u002F\u002F 组合：过滤 + 排序\n",[228,1126,1128,1131,1133,1135,1137,1139],{"class":230,"line":1127},16,[228,1129,1130],{"class":317},"  filteredAndSorted",[228,1132,841],{"class":238},[228,1134,845],{"class":844},[228,1136,376],{"class":238},[228,1138,850],{"class":234},[228,1140,853],{"class":238},[228,1142,1144,1147,1150,1153],{"class":230,"line":1143},17,[228,1145,1146],{"class":234},"    let",[228,1148,1149],{"class":238}," result ",[228,1151,1152],{"class":234},"=",[228,1154,1009],{"class":238},[228,1156,1158],{"class":230,"line":1157},18,[228,1159,1160],{"class":275},"    \u002F\u002F 先过滤\n",[228,1162,1164,1166],{"class":230,"line":1163},19,[228,1165,995],{"class":234},[228,1167,1168],{"class":238}," (state.searchKeyword) {\n",[228,1170,1172,1175,1177,1180,1182,1184,1186,1188,1191,1193],{"class":230,"line":1171},20,[228,1173,1174],{"class":238},"      result ",[228,1176,1152],{"class":234},[228,1178,1179],{"class":238}," result.",[228,1181,1018],{"class":317},[228,1183,370],{"class":238},[228,1185,10],{"class":844},[228,1187,871],{"class":234},[228,1189,1190],{"class":238}," p.name.",[228,1192,1033],{"class":317},[228,1194,1195],{"class":238},"(state.searchKeyword))\n",[228,1197,1199],{"class":230,"line":1198},21,[228,1200,1201],{"class":238},"    }\n",[228,1203,1205],{"class":230,"line":1204},22,[228,1206,1207],{"class":275},"    \u002F\u002F 再排序\n",[228,1209,1211,1213,1215,1217,1220,1222,1224,1226,1228,1230,1232,1234,1236,1238],{"class":230,"line":1210},23,[228,1212,858],{"class":234},[228,1214,1076],{"class":238},[228,1216,1079],{"class":234},[228,1218,1219],{"class":238},"result].",[228,1221,1085],{"class":317},[228,1223,1088],{"class":238},[228,1225,1091],{"class":844},[228,1227,476],{"class":238},[228,1229,1096],{"class":844},[228,1231,376],{"class":238},[228,1233,850],{"class":234},[228,1235,1103],{"class":238},[228,1237,1106],{"class":234},[228,1239,1109],{"class":238},[228,1241,1243],{"class":230,"line":1242},24,[228,1244,950],{"class":238},[228,1246,1248],{"class":230,"line":1247},25,[228,1249,956],{"class":238},[10,1251,1252],{},"一些统计数据的场景可以在这里很方便的实现。",[10,1254,1255],{},"带参数的 Getter（动态查询）",[90,1257,1261],{"className":1258,"code":1259,"language":1260,"meta":99,"style":99},"language-typescript shiki shiki-themes github-light github-dark","getters: {\n  \u002F\u002F 返回函数，接收参数\n  getPersonById: (state) => (id: number) => {\n    return state.peopleList.find(p => p.id === id)\n  },\n  getPeopleByAgeRange: (state) => (min: number, max: number) => {\n    return state.peopleList.filter(p => p.age >= min && p.age \u003C= max)\n  },\n}\n","typescript",[97,1262,1263,1269,1274,1304,1327,1331,1368,1402,1406],{"__ignoreMap":99},[228,1264,1265,1267],{"class":230,"line":231},[228,1266,643],{"class":317},[228,1268,812],{"class":238},[228,1270,1271],{"class":230,"line":249},[228,1272,1273],{"class":275},"  \u002F\u002F 返回函数，接收参数\n",[228,1275,1276,1279,1281,1283,1285,1287,1289,1292,1295,1298,1300,1302],{"class":230,"line":262},[228,1277,1278],{"class":317},"  getPersonById",[228,1280,841],{"class":238},[228,1282,845],{"class":844},[228,1284,376],{"class":238},[228,1286,850],{"class":234},[228,1288,998],{"class":238},[228,1290,1291],{"class":844},"id",[228,1293,1294],{"class":234},":",[228,1296,1297],{"class":310}," number",[228,1299,376],{"class":238},[228,1301,850],{"class":234},[228,1303,853],{"class":238},[228,1305,1306,1308,1310,1313,1315,1317,1319,1322,1324],{"class":230,"line":279},[228,1307,858],{"class":234},[228,1309,861],{"class":238},[228,1311,1312],{"class":317},"find",[228,1314,370],{"class":238},[228,1316,10],{"class":844},[228,1318,871],{"class":234},[228,1320,1321],{"class":238}," p.id ",[228,1323,922],{"class":234},[228,1325,1326],{"class":238}," id)\n",[228,1328,1329],{"class":230,"line":285},[228,1330,950],{"class":238},[228,1332,1333,1336,1338,1340,1342,1344,1346,1349,1351,1353,1355,1358,1360,1362,1364,1366],{"class":230,"line":298},[228,1334,1335],{"class":317},"  getPeopleByAgeRange",[228,1337,841],{"class":238},[228,1339,845],{"class":844},[228,1341,376],{"class":238},[228,1343,850],{"class":234},[228,1345,998],{"class":238},[228,1347,1348],{"class":844},"min",[228,1350,1294],{"class":234},[228,1352,1297],{"class":310},[228,1354,476],{"class":238},[228,1356,1357],{"class":844},"max",[228,1359,1294],{"class":234},[228,1361,1297],{"class":310},[228,1363,376],{"class":238},[228,1365,850],{"class":234},[228,1367,853],{"class":238},[228,1369,1370,1372,1374,1376,1378,1380,1382,1385,1388,1391,1394,1396,1399],{"class":230,"line":304},[228,1371,858],{"class":234},[228,1373,861],{"class":238},[228,1375,1018],{"class":317},[228,1377,370],{"class":238},[228,1379,10],{"class":844},[228,1381,871],{"class":234},[228,1383,1384],{"class":238}," p.age ",[228,1386,1387],{"class":234},">=",[228,1389,1390],{"class":238}," min ",[228,1392,1393],{"class":234},"&&",[228,1395,1384],{"class":238},[228,1397,1398],{"class":234},"\u003C=",[228,1400,1401],{"class":238}," max)\n",[228,1403,1404],{"class":230,"line":324},[228,1405,950],{"class":238},[228,1407,1408],{"class":230,"line":340},[228,1409,956],{"class":238},[10,1411,1412],{},"以及可以用于跨store调用的数据的场景，用这种方式可以继续压缩业务代码，防止在vue模板文件中减少代码量。",[90,1414,1416],{"className":222,"code":1415,"language":224,"meta":99,"style":99},"\u002F\u002F store\u002Fpeople.ts\nimport { useAuthStore } from '.\u002Fauth'\n\ngetters: {\n  \u002F\u002F 访问其他 Store\n  currentUserPeople: (state) => {\n    const authStore = useAuthStore()\n    return state.peopleList.filter(p => p.userId === authStore.userId)\n  },\n}\n",[97,1417,1418,1423,1435,1439,1445,1450,1465,1480,1502,1506],{"__ignoreMap":99},[228,1419,1420],{"class":230,"line":231},[228,1421,1422],{"class":275},"\u002F\u002F store\u002Fpeople.ts\n",[228,1424,1425,1427,1430,1432],{"class":230,"line":249},[228,1426,235],{"class":234},[228,1428,1429],{"class":238}," { useAuthStore } ",[228,1431,242],{"class":234},[228,1433,1434],{"class":245}," '.\u002Fauth'\n",[228,1436,1437],{"class":230,"line":262},[228,1438,828],{"emptyLinePlaceholder":827},[228,1440,1441,1443],{"class":230,"line":279},[228,1442,643],{"class":317},[228,1444,812],{"class":238},[228,1446,1447],{"class":230,"line":285},[228,1448,1449],{"class":275},"  \u002F\u002F 访问其他 Store\n",[228,1451,1452,1455,1457,1459,1461,1463],{"class":230,"line":298},[228,1453,1454],{"class":317},"  currentUserPeople",[228,1456,841],{"class":238},[228,1458,845],{"class":844},[228,1460,376],{"class":238},[228,1462,850],{"class":234},[228,1464,853],{"class":238},[228,1466,1467,1470,1473,1475,1478],{"class":230,"line":304},[228,1468,1469],{"class":234},"    const",[228,1471,1472],{"class":310}," authStore",[228,1474,314],{"class":234},[228,1476,1477],{"class":317}," useAuthStore",[228,1479,337],{"class":238},[228,1481,1482,1484,1486,1488,1490,1492,1494,1497,1499],{"class":230,"line":324},[228,1483,858],{"class":234},[228,1485,861],{"class":238},[228,1487,1018],{"class":317},[228,1489,370],{"class":238},[228,1491,10],{"class":844},[228,1493,871],{"class":234},[228,1495,1496],{"class":238}," p.userId ",[228,1498,922],{"class":234},[228,1500,1501],{"class":238}," authStore.userId)\n",[228,1503,1504],{"class":230,"line":340},[228,1505,950],{"class":238},[228,1507,1508],{"class":230,"line":352},[228,1509,956],{"class":238},[33,1511,1512],{"id":1512},"pinia插件",[10,1514,1515,1516,1519,1520,1523,1524,1529],{},"Pinia 插件是一个普通函数，通过 ",[97,1517,1518],{},"pinia.use()"," 注册，可以为",[14,1521,1522],{},"核心的状态管理添加全局能力","，比如在 store 上挂载公共属性、封装可复用的逻辑、添加加密存储等，对大量 store 统一进行增强",[1091,1525],{"href":1526,"rel":1527},"https:\u002F\u002Fpinia.vuejs.org\u002Fcore-concepts\u002Fplugins",[1528],"nofollow",[1091,1530],{"href":1531,"rel":1532},"https:\u002F\u002Fcloud.tencent.com.cn\u002Fdeveloper\u002Farticle\u002F2528008",[1528],[90,1534,1536],{"className":222,"code":1535,"language":224,"meta":99,"style":99},"export function myPiniaPlugin(context) {\n  context.pinia \u002F\u002F 用 `createPinia()` 创建的 pinia。\n  context.app \u002F\u002F 用 `createApp()` 创建的当前应用(仅 Vue 3)。\n  context.store \u002F\u002F 该插件想扩展的 store\n  context.options \u002F\u002F 定义传给 `defineStore()` 的 store 的可选对象。\n  \u002F\u002F ...\n}\n",[97,1537,1538,1556,1564,1572,1580,1588,1593],{"__ignoreMap":99},[228,1539,1540,1542,1545,1548,1550,1553],{"class":230,"line":231},[228,1541,748],{"class":234},[228,1543,1544],{"class":234}," function",[228,1546,1547],{"class":317}," myPiniaPlugin",[228,1549,370],{"class":238},[228,1551,1552],{"class":844},"context",[228,1554,1555],{"class":238},") {\n",[228,1557,1558,1561],{"class":230,"line":249},[228,1559,1560],{"class":238},"  context.pinia ",[228,1562,1563],{"class":275},"\u002F\u002F 用 `createPinia()` 创建的 pinia。\n",[228,1565,1566,1569],{"class":230,"line":262},[228,1567,1568],{"class":238},"  context.app ",[228,1570,1571],{"class":275},"\u002F\u002F 用 `createApp()` 创建的当前应用(仅 Vue 3)。\n",[228,1573,1574,1577],{"class":230,"line":279},[228,1575,1576],{"class":238},"  context.store ",[228,1578,1579],{"class":275},"\u002F\u002F 该插件想扩展的 store\n",[228,1581,1582,1585],{"class":230,"line":285},[228,1583,1584],{"class":238},"  context.options ",[228,1586,1587],{"class":275},"\u002F\u002F 定义传给 `defineStore()` 的 store 的可选对象。\n",[228,1589,1590],{"class":230,"line":298},[228,1591,1592],{"class":275},"  \u002F\u002F ...\n",[228,1594,1595],{"class":230,"line":304},[228,1596,956],{"class":238},[10,1598,1599,1600,1603,1604,1607,1608,1611],{},"比如说，我们可以使用 ",[14,1601,1602],{},"Pinia 插件"," 配合 ",[14,1605,1606],{},"VueUse"," 的 ",[97,1609,1610],{},"useDebounceFn","，给任意 action 自动加上防抖，避免重复触发，这里我们需要使用ts的模块扩展语法来告诉ts这个模块\u002F类型是存在的，即使我找不到它的定义”。",[90,1613,1615],{"className":222,"code":1614,"language":224,"meta":99,"style":99},"declare module 'pinia' {\n  export interface DefineStoreOptionsBase\u003CS, Store> {\n    debounce?: Record\u003Cstring, number>\n  }\n}\n",[97,1616,1617,1630,1655,1679,1684],{"__ignoreMap":99},[228,1618,1619,1622,1625,1628],{"class":230,"line":231},[228,1620,1621],{"class":234},"declare",[228,1623,1624],{"class":234}," module",[228,1626,1627],{"class":245}," 'pinia'",[228,1629,853],{"class":238},[228,1631,1632,1635,1638,1641,1644,1647,1649,1652],{"class":230,"line":249},[228,1633,1634],{"class":234},"  export",[228,1636,1637],{"class":234}," interface",[228,1639,1640],{"class":317}," DefineStoreOptionsBase",[228,1642,1643],{"class":238},"\u003C",[228,1645,1646],{"class":317},"S",[228,1648,476],{"class":238},[228,1650,1651],{"class":317},"Store",[228,1653,1654],{"class":238},"> {\n",[228,1656,1657,1660,1663,1666,1668,1671,1673,1676],{"class":230,"line":262},[228,1658,1659],{"class":844},"    debounce",[228,1661,1662],{"class":234},"?:",[228,1664,1665],{"class":317}," Record",[228,1667,1643],{"class":238},[228,1669,1670],{"class":310},"string",[228,1672,476],{"class":238},[228,1674,1675],{"class":310},"number",[228,1677,1678],{"class":238},">\n",[228,1680,1681],{"class":230,"line":279},[228,1682,1683],{"class":238},"  }\n",[228,1685,1686],{"class":230,"line":285},[228,1687,956],{"class":238},[10,1689,1690,1691,1694,1695,1698],{},"现在在 ",[97,1692,1693],{},"defineStore"," 中可以使用 ",[97,1696,1697],{},"debounce"," 选项，TypeScript 不会报错，并且有类型提示。",[10,1700,1701],{},"我们去识别store中是否有debounce然后去实现将普通方法通过vueuse的防抖注册为防抖办法，用于我们自己的store中方法：",[90,1703,1705],{"className":222,"code":1704,"language":224,"meta":99,"style":99},"\u002F* eslint-disable @typescript-eslint\u002Fno-unused-vars *\u002F\n\u002F\u002F plugins\u002Fpinia-debounce.ts\nimport type { PiniaPluginContext, Pinia } from 'pinia'\nimport { useDebounceFn } from '@vueuse\u002Fcore'\ndeclare module 'pinia' {\n  export interface DefineStoreOptionsBase\u003CS, Store> {\n    debounce?: Record\u003Cstring, number>\n  }\n}\nexport function createDebouncePlugin() {\n  return (context: PiniaPluginContext) => {\n    const { options, store } = context\n    if (!options.debounce) return\n    const debouncedActions: Record\u003Cstring, unknown> = {}\n    Object.entries(options.debounce).forEach(([actionsName, delay]) => {\n      const originalAction = store[actionsName]\n      if (typeof originalAction !== 'function') return\n      debouncedActions[actionsName] = useDebounceFn(\n        originalAction.bind(store),\n        delay\n      )\n    })\n    return debouncedActions\n  }\n}\n  \nexport default defineNuxtPlugin((nuxtApp) => {\n  const pinia = nuxtApp.$pinia as Pinia\n  pinia.use(createDebouncePlugin())\n})\n",[97,1706,1707,1712,1717,1731,1743,1753,1772,1791,1796,1800,1812,1832,1855,1870,1898,1930,1943,1966,1979,1990,1995,2000,2005,2013,2017,2021,2027,2049,2068,2084],{"__ignoreMap":99},[228,1708,1709],{"class":230,"line":231},[228,1710,1711],{"class":275},"\u002F* eslint-disable @typescript-eslint\u002Fno-unused-vars *\u002F\n",[228,1713,1714],{"class":230,"line":249},[228,1715,1716],{"class":275},"\u002F\u002F plugins\u002Fpinia-debounce.ts\n",[228,1718,1719,1721,1724,1727,1729],{"class":230,"line":262},[228,1720,235],{"class":234},[228,1722,1723],{"class":234}," type",[228,1725,1726],{"class":238}," { PiniaPluginContext, Pinia } ",[228,1728,242],{"class":234},[228,1730,259],{"class":245},[228,1732,1733,1735,1738,1740],{"class":230,"line":279},[228,1734,235],{"class":234},[228,1736,1737],{"class":238}," { useDebounceFn } ",[228,1739,242],{"class":234},[228,1741,1742],{"class":245}," '@vueuse\u002Fcore'\n",[228,1744,1745,1747,1749,1751],{"class":230,"line":285},[228,1746,1621],{"class":234},[228,1748,1624],{"class":234},[228,1750,1627],{"class":245},[228,1752,853],{"class":238},[228,1754,1755,1758,1760,1762,1764,1766,1768,1770],{"class":230,"line":298},[228,1756,1757],{"class":234},"  export",[228,1759,1637],{"class":234},[228,1761,1640],{"class":317},[228,1763,1643],{"class":238},[228,1765,1646],{"class":317},[228,1767,476],{"class":238},[228,1769,1651],{"class":317},[228,1771,1654],{"class":238},[228,1773,1774,1777,1779,1781,1783,1785,1787,1789],{"class":230,"line":304},[228,1775,1776],{"class":844},"    debounce",[228,1778,1662],{"class":234},[228,1780,1665],{"class":317},[228,1782,1643],{"class":238},[228,1784,1670],{"class":310},[228,1786,476],{"class":238},[228,1788,1675],{"class":310},[228,1790,1678],{"class":238},[228,1792,1793],{"class":230,"line":324},[228,1794,1795],{"class":238},"  }\n",[228,1797,1798],{"class":230,"line":340},[228,1799,956],{"class":238},[228,1801,1802,1804,1806,1809],{"class":230,"line":352},[228,1803,748],{"class":234},[228,1805,1544],{"class":234},[228,1807,1808],{"class":317}," createDebouncePlugin",[228,1810,1811],{"class":238},"() {\n",[228,1813,1814,1817,1819,1821,1823,1826,1828,1830],{"class":230,"line":362},[228,1815,1816],{"class":234},"  return",[228,1818,998],{"class":238},[228,1820,1552],{"class":844},[228,1822,1294],{"class":234},[228,1824,1825],{"class":317}," PiniaPluginContext",[228,1827,376],{"class":238},[228,1829,850],{"class":234},[228,1831,853],{"class":238},[228,1833,1834,1837,1840,1843,1845,1847,1850,1852],{"class":230,"line":947},[228,1835,1836],{"class":234},"    const",[228,1838,1839],{"class":238}," { ",[228,1841,1842],{"class":310},"options",[228,1844,476],{"class":238},[228,1846,488],{"class":310},[228,1848,1849],{"class":238}," } ",[228,1851,1152],{"class":234},[228,1853,1854],{"class":238}," context\n",[228,1856,1857,1860,1862,1864,1867],{"class":230,"line":953},[228,1858,1859],{"class":234},"    if",[228,1861,998],{"class":238},[228,1863,1001],{"class":234},[228,1865,1866],{"class":238},"options.debounce) ",[228,1868,1869],{"class":234},"return\n",[228,1871,1872,1874,1877,1879,1881,1883,1885,1887,1890,1893,1895],{"class":230,"line":1116},[228,1873,1836],{"class":234},[228,1875,1876],{"class":310}," debouncedActions",[228,1878,1294],{"class":234},[228,1880,1665],{"class":317},[228,1882,1643],{"class":238},[228,1884,1670],{"class":310},[228,1886,476],{"class":238},[228,1888,1889],{"class":310},"unknown",[228,1891,1892],{"class":238},"> ",[228,1894,1152],{"class":234},[228,1896,1897],{"class":238}," {}\n",[228,1899,1900,1903,1906,1909,1912,1915,1918,1920,1923,1926,1928],{"class":230,"line":1121},[228,1901,1902],{"class":238},"    Object.",[228,1904,1905],{"class":317},"entries",[228,1907,1908],{"class":238},"(options.debounce).",[228,1910,1911],{"class":317},"forEach",[228,1913,1914],{"class":238},"(([",[228,1916,1917],{"class":844},"actionsName",[228,1919,476],{"class":238},[228,1921,1922],{"class":844},"delay",[228,1924,1925],{"class":238},"]) ",[228,1927,850],{"class":234},[228,1929,853],{"class":238},[228,1931,1932,1935,1938,1940],{"class":230,"line":1127},[228,1933,1934],{"class":234},"      const",[228,1936,1937],{"class":310}," originalAction",[228,1939,314],{"class":234},[228,1941,1942],{"class":238}," store[actionsName]\n",[228,1944,1945,1948,1950,1953,1956,1959,1962,1964],{"class":230,"line":1143},[228,1946,1947],{"class":234},"      if",[228,1949,998],{"class":238},[228,1951,1952],{"class":234},"typeof",[228,1954,1955],{"class":238}," originalAction ",[228,1957,1958],{"class":234},"!==",[228,1960,1961],{"class":245}," 'function'",[228,1963,376],{"class":238},[228,1965,1869],{"class":234},[228,1967,1968,1971,1973,1976],{"class":230,"line":1157},[228,1969,1970],{"class":238},"      debouncedActions[actionsName] ",[228,1972,1152],{"class":234},[228,1974,1975],{"class":317}," useDebounceFn",[228,1977,1978],{"class":238},"(\n",[228,1980,1981,1984,1987],{"class":230,"line":1163},[228,1982,1983],{"class":238},"        originalAction.",[228,1985,1986],{"class":317},"bind",[228,1988,1989],{"class":238},"(store),\n",[228,1991,1992],{"class":230,"line":1171},[228,1993,1994],{"class":238},"        delay\n",[228,1996,1997],{"class":230,"line":1198},[228,1998,1999],{"class":238},"      )\n",[228,2001,2002],{"class":230,"line":1204},[228,2003,2004],{"class":238},"    })\n",[228,2006,2007,2010],{"class":230,"line":1210},[228,2008,2009],{"class":234},"    return",[228,2011,2012],{"class":238}," debouncedActions\n",[228,2014,2015],{"class":230,"line":1242},[228,2016,1795],{"class":238},[228,2018,2019],{"class":230,"line":1247},[228,2020,956],{"class":238},[228,2022,2024],{"class":230,"line":2023},26,[228,2025,2026],{"class":238},"  \n",[228,2028,2030,2032,2035,2038,2040,2043,2045,2047],{"class":230,"line":2029},27,[228,2031,748],{"class":234},[228,2033,2034],{"class":234}," default",[228,2036,2037],{"class":317}," defineNuxtPlugin",[228,2039,1088],{"class":238},[228,2041,2042],{"class":844},"nuxtApp",[228,2044,376],{"class":238},[228,2046,850],{"class":234},[228,2048,853],{"class":238},[228,2050,2052,2055,2057,2059,2062,2065],{"class":230,"line":2051},28,[228,2053,2054],{"class":234},"  const",[228,2056,329],{"class":310},[228,2058,314],{"class":234},[228,2060,2061],{"class":238}," nuxtApp.$pinia ",[228,2063,2064],{"class":234},"as",[228,2066,2067],{"class":317}," Pinia\n",[228,2069,2071,2074,2076,2078,2081],{"class":230,"line":2070},29,[228,2072,2073],{"class":238},"  pinia.",[228,2075,346],{"class":317},[228,2077,370],{"class":238},[228,2079,2080],{"class":317},"createDebouncePlugin",[228,2082,2083],{"class":238},"())\n",[228,2085,2087],{"class":230,"line":2086},30,[228,2088,2089],{"class":238},"})\n",[33,2091,2092],{"id":2092},"持久化",[10,2094,2095,2096,2099,2100,2103,2104,2108,2112,2116,2117,2120],{}," Pinia 持久化，核心原理非常清晰：通过 ",[97,2097,2098],{},"store.$subscribe"," 监听状态变化并存入本地存储，再在 store 初始化时从存储中读取数据，通过 ",[97,2101,2102],{},"store.$patch"," 恢复状态",[1091,2105],{"href":2106,"rel":2107},"https:\u002F\u002Fblog.csdn.net\u002Fweixin_62936589\u002Farticle\u002Fdetails\u002F143031003",[1528],[1091,2109],{"href":2110,"rel":2111},"https:\u002F\u002Fcloud.tencent.cn\u002Fdeveloper\u002Farticle\u002F2567715",[1528],[1091,2113],{"href":2114,"rel":2115},"https:\u002F\u002Fjuejin.cn\u002Fpost\u002F7212435153573609529",[1528],"。目前社区最主流、也最推荐的做法，就是使用 ",[97,2118,2119],{},"pinia-plugin-persistedstate"," 这个官方生态插件。",[10,2122,2123],{},"可以从指令安装：",[90,2125,2128],{"className":2126,"code":2127,"language":95},[93],"pnpm add pinia-plugin-persistedstate\n",[97,2129,2127],{"__ignoreMap":99},[10,2131,2132,2133,2136,2137,2142,2143,2145],{},"此插件与 ",[97,2134,2135],{},"pinia>=2.0.0"," 兼容， 请确保在继续之前 ",[1091,2138,2141],{"href":2139,"rel":2140},"https:\u002F\u002Fpinia.vuejs.org\u002Fgetting-started.html",[1528],"已安装 Pinia"," 。 ",[97,2144,2119],{}," 具有许多功能，使 Pinia store 的持久化变得轻松且可配置：",[161,2147,2148,2159,2162,2165,2168],{},[41,2149,2150,2151,2158],{},"一个类似于 ",[1091,2152,2155],{"href":2153,"rel":2154},"https:\u002F\u002Fgithub.com\u002Frobinvdvleuten\u002Fvuex-persistedstate",[1528],[97,2156,2157],{},"vuex-persistedstate","的 API。",[41,2160,2161],{},"Per-store 配置.",[41,2163,2164],{},"自定义存储和自定义数据序列化程序。",[41,2166,2167],{},"Pre\u002Fpost persistence\u002Fhydration hooks.",[41,2169,2170],{},"每个store有多个配置。",[10,2172,2173],{},"这个包可以导出一个模块，能够更好的和nuxt集成和开箱即用的ssr支持，",[10,2175,2176],{},"将插件添加到你的 pinia 实例中：",[90,2178,2180],{"className":222,"code":2179,"language":224,"meta":99,"style":99},"import { createPinia } from 'pinia'\nimport piniaPluginPersistedstate from 'pinia-plugin-persistedstate'\n\nconst pinia = createPinia()\npinia.use(piniaPluginPersistedstate)\n",[97,2181,2182,2192,2204,2208,2220],{"__ignoreMap":99},[228,2183,2184,2186,2188,2190],{"class":230,"line":231},[228,2185,235],{"class":234},[228,2187,254],{"class":238},[228,2189,242],{"class":234},[228,2191,259],{"class":245},[228,2193,2194,2196,2199,2201],{"class":230,"line":249},[228,2195,235],{"class":234},[228,2197,2198],{"class":238}," piniaPluginPersistedstate ",[228,2200,242],{"class":234},[228,2202,2203],{"class":245}," 'pinia-plugin-persistedstate'\n",[228,2205,2206],{"class":230,"line":262},[228,2207,828],{"emptyLinePlaceholder":827},[228,2209,2210,2212,2214,2216,2218],{"class":230,"line":279},[228,2211,307],{"class":234},[228,2213,329],{"class":310},[228,2215,314],{"class":234},[228,2217,334],{"class":317},[228,2219,337],{"class":238},[228,2221,2222,2225,2227],{"class":230,"line":285},[228,2223,2224],{"class":238},"pinia.",[228,2226,346],{"class":317},[228,2228,2229],{"class":238},"(piniaPluginPersistedstate)\n",[10,2231,2232,2233,2236,2237,24],{},"在声明store时，请将新",[97,2234,2235],{},"persist","选项设置为 ",[97,2238,2239],{},"true",[90,2241,2243],{"className":222,"code":2242,"language":224,"meta":99,"style":99},"import { defineStore } from 'pinia'\n\nexport const useStore = defineStore('main', {\n  state: () => {\n    return {\n      someState: 'hello pinia',\n    }\n  },\n  persist: true,\n})\n",[97,2244,2245,2256,2260,2283,2295,2301,2311,2315,2319,2328],{"__ignoreMap":99},[228,2246,2247,2249,2252,2254],{"class":230,"line":231},[228,2248,235],{"class":234},[228,2250,2251],{"class":238}," { defineStore } ",[228,2253,242],{"class":234},[228,2255,259],{"class":245},[228,2257,2258],{"class":230,"line":249},[228,2259,828],{"emptyLinePlaceholder":827},[228,2261,2262,2264,2267,2270,2272,2275,2277,2280],{"class":230,"line":262},[228,2263,748],{"class":234},[228,2265,2266],{"class":234}," const",[228,2268,2269],{"class":310}," useStore",[228,2271,314],{"class":234},[228,2273,2274],{"class":317}," defineStore",[228,2276,370],{"class":238},[228,2278,2279],{"class":245},"'main'",[228,2281,2282],{"class":238},", {\n",[228,2284,2285,2288,2291,2293],{"class":230,"line":279},[228,2286,2287],{"class":317},"  state",[228,2289,2290],{"class":238},": () ",[228,2292,850],{"class":234},[228,2294,853],{"class":238},[228,2296,2297,2299],{"class":230,"line":285},[228,2298,858],{"class":234},[228,2300,853],{"class":238},[228,2302,2303,2306,2309],{"class":230,"line":298},[228,2304,2305],{"class":238},"      someState: ",[228,2307,2308],{"class":245},"'hello pinia'",[228,2310,914],{"class":238},[228,2312,2313],{"class":230,"line":304},[228,2314,1201],{"class":238},[228,2316,2317],{"class":230,"line":324},[228,2318,950],{"class":238},[228,2320,2321,2324,2326],{"class":230,"line":340},[228,2322,2323],{"class":238},"  persist: ",[228,2325,2239],{"class":310},[228,2327,914],{"class":238},[228,2329,2330],{"class":230,"line":352},[228,2331,2089],{"class":238},[10,2333,2334,2335,2340],{},"整个 store 现在将使用 ",[1091,2336,2339],{"href":2337,"rel":2338},"https:\u002F\u002Fprazdevs.github.io\u002Fpinia-plugin-persistedstate\u002Fguide\u002Fconfig.html",[1528],"默认的持久性设置","进行保存。这个插件提前将localStorage作为存储，store.$id作为默认存储键，使用JSON.stringfy作为序列化器和反序列化器，与destr进行通信。",[10,2342,2343,2344,2346],{},"与 Nuxt 模块相比，默认设置有一些不同，因为它能提供更适合 SSR 体验的配置。如需了解更多信息，请参考 Nuxt 的使用文档。你可以将一个对象传递给商店的 ",[97,2345,2235],{}," 属性，以配置持久化功能。",[10,2348,2349,2350,2353,2354,2357,2358,24],{},"你可以通过使用自动导入的 ",[97,2351,2352],{},"piniaPluginPersistedstate"," 变量中提供的",[14,2355,2356],{},"存储选项","，来配置想要使用的",[14,2359,2360],{},"存储类型",[10,2362,2363],{},"比如使用cookies作为存储方式：",[90,2365,2367],{"className":222,"code":2366,"language":224,"meta":99,"style":99},"import { defineStore } from 'pinia'\n\nexport const useStore = defineStore('main', {\n  state: () => {\n    return {\n      someState: 'hello pinia',\n    }\n  },\n  persist: {\n    storage: piniaPluginPersistedstate.cookies(),\n  },\n})\n",[97,2368,2369,2379,2383,2401,2411,2417,2425,2429,2433,2438,2449,2453],{"__ignoreMap":99},[228,2370,2371,2373,2375,2377],{"class":230,"line":231},[228,2372,235],{"class":234},[228,2374,2251],{"class":238},[228,2376,242],{"class":234},[228,2378,259],{"class":245},[228,2380,2381],{"class":230,"line":249},[228,2382,828],{"emptyLinePlaceholder":827},[228,2384,2385,2387,2389,2391,2393,2395,2397,2399],{"class":230,"line":262},[228,2386,748],{"class":234},[228,2388,2266],{"class":234},[228,2390,2269],{"class":310},[228,2392,314],{"class":234},[228,2394,2274],{"class":317},[228,2396,370],{"class":238},[228,2398,2279],{"class":245},[228,2400,2282],{"class":238},[228,2402,2403,2405,2407,2409],{"class":230,"line":279},[228,2404,2287],{"class":317},[228,2406,2290],{"class":238},[228,2408,850],{"class":234},[228,2410,853],{"class":238},[228,2412,2413,2415],{"class":230,"line":285},[228,2414,858],{"class":234},[228,2416,853],{"class":238},[228,2418,2419,2421,2423],{"class":230,"line":298},[228,2420,2305],{"class":238},[228,2422,2308],{"class":245},[228,2424,914],{"class":238},[228,2426,2427],{"class":230,"line":304},[228,2428,1201],{"class":238},[228,2430,2431],{"class":230,"line":324},[228,2432,950],{"class":238},[228,2434,2435],{"class":230,"line":340},[228,2436,2437],{"class":238},"  persist: {\n",[228,2439,2440,2443,2446],{"class":230,"line":352},[228,2441,2442],{"class":238},"    storage: piniaPluginPersistedstate.",[228,2444,2445],{"class":317},"cookies",[228,2447,2448],{"class":238},"(),\n",[228,2450,2451],{"class":230,"line":362},[228,2452,950],{"class":238},[228,2454,2455],{"class":230,"line":947},[228,2456,2089],{"class":238},[10,2458,2459,2462,2463,2466],{},[97,2460,2461],{},"persistedState.cookies"," 方法接受一个对象参数，用于配置 cookies，支持以下选项（这些选项继承自 Nuxt 的 ",[97,2464,2465],{},"useCookie"," 方法）：",[161,2468,2469,2478,2495,2504,2513,2521,2530,2539,2548],{},[41,2470,2471],{},[1091,2472,2475],{"href":2473,"rel":2474},"https:\u002F\u002Fnuxt.com\u002Fdocs\u002Fapi\u002Fcomposables\u002Fuse-cookie#domain",[1528],[97,2476,2477],{},"domain",[41,2479,2480,2487,2488],{},[1091,2481,2484],{"href":2482,"rel":2483},"https:\u002F\u002Fnuxt.com\u002Fdocs\u002Fapi\u002Fcomposables\u002Fuse-cookie#encode",[1528],[97,2485,2486],{},"encode","\u002F",[1091,2489,2492],{"href":2490,"rel":2491},"https:\u002F\u002Fnuxt.com\u002Fdocs\u002Fapi\u002Fcomposables\u002Fuse-cookie#decode",[1528],[97,2493,2494],{},"decode",[41,2496,2497],{},[1091,2498,2501],{"href":2499,"rel":2500},"https:\u002F\u002Fnuxt.com\u002Fdocs\u002Fapi\u002Fcomposables\u002Fuse-cookie#maxage-expires",[1528],[97,2502,2503],{},"expires",[41,2505,2506],{},[1091,2507,2510],{"href":2508,"rel":2509},"https:\u002F\u002Fnuxt.com\u002Fdocs\u002Fapi\u002Fcomposables\u002Fuse-cookie#httponly",[1528],[97,2511,2512],{},"httpOnly",[41,2514,2515],{},[1091,2516,2518],{"href":2499,"rel":2517},[1528],[97,2519,2520],{},"maxAge",[41,2522,2523],{},[1091,2524,2527],{"href":2525,"rel":2526},"https:\u002F\u002Fnuxt.com\u002Fdocs\u002Fapi\u002Fcomposables\u002Fuse-cookie#partitioned",[1528],[97,2528,2529],{},"partitioned",[41,2531,2532],{},[1091,2533,2536],{"href":2534,"rel":2535},"https:\u002F\u002Fnuxt.com\u002Fdocs\u002Fapi\u002Fcomposables\u002Fuse-cookie#path",[1528],[97,2537,2538],{},"path",[41,2540,2541],{},[1091,2542,2545],{"href":2543,"rel":2544},"https:\u002F\u002Fnuxt.com\u002Fdocs\u002Fapi\u002Fcomposables\u002Fuse-cookie#samesite",[1528],[97,2546,2547],{},"sameSite",[41,2549,2550],{},[1091,2551,2554],{"href":2552,"rel":2553},"https:\u002F\u002Fnuxt.com\u002Fdocs\u002Fapi\u002Fcomposables\u002Fuse-cookie#secure",[1528],[97,2555,2556],{},"secure",[2558,2559,2560],"blockquote",{},[10,2561,2562,2565],{},[228,2563,2564],{},"!warning"," 在保存包含大量数据的存储时需要注意，因为 cookie 的大小限制为 4098 字节。有关 cookie 存储的更多信息，请参阅 MDN 文档。",[10,2567,2568,590],{},[97,2569,2570],{},"localStorage",[90,2572,2574],{"className":222,"code":2573,"language":224,"meta":99,"style":99},"import { defineStore } from 'pinia'\n\nexport const useStore = defineStore('main', {\n  state: () => {\n    return {\n      someState: 'hello pinia',\n    }\n  },\n  persist: {\n    storage: piniaPluginPersistedstate.localStorage(),\n  },\n})\n",[97,2575,2576,2586,2590,2608,2618,2624,2632,2636,2640,2644,2652,2656],{"__ignoreMap":99},[228,2577,2578,2580,2582,2584],{"class":230,"line":231},[228,2579,235],{"class":234},[228,2581,2251],{"class":238},[228,2583,242],{"class":234},[228,2585,259],{"class":245},[228,2587,2588],{"class":230,"line":249},[228,2589,828],{"emptyLinePlaceholder":827},[228,2591,2592,2594,2596,2598,2600,2602,2604,2606],{"class":230,"line":262},[228,2593,748],{"class":234},[228,2595,2266],{"class":234},[228,2597,2269],{"class":310},[228,2599,314],{"class":234},[228,2601,2274],{"class":317},[228,2603,370],{"class":238},[228,2605,2279],{"class":245},[228,2607,2282],{"class":238},[228,2609,2610,2612,2614,2616],{"class":230,"line":279},[228,2611,2287],{"class":317},[228,2613,2290],{"class":238},[228,2615,850],{"class":234},[228,2617,853],{"class":238},[228,2619,2620,2622],{"class":230,"line":285},[228,2621,858],{"class":234},[228,2623,853],{"class":238},[228,2625,2626,2628,2630],{"class":230,"line":298},[228,2627,2305],{"class":238},[228,2629,2308],{"class":245},[228,2631,914],{"class":238},[228,2633,2634],{"class":230,"line":304},[228,2635,1201],{"class":238},[228,2637,2638],{"class":230,"line":324},[228,2639,950],{"class":238},[228,2641,2642],{"class":230,"line":340},[228,2643,2437],{"class":238},[228,2645,2646,2648,2650],{"class":230,"line":352},[228,2647,2442],{"class":238},[228,2649,2570],{"class":317},[228,2651,2448],{"class":238},[228,2653,2654],{"class":230,"line":362},[228,2655,950],{"class":238},[228,2657,2658],{"class":230,"line":947},[228,2659,2089],{"class":238},[10,2661,2662],{},[97,2663,2664],{},"sessionStorage",[90,2666,2668],{"className":222,"code":2667,"language":224,"meta":99,"style":99},"import { defineStore } from 'pinia'\n\nexport const useStore = defineStore('main', {\n  state: () => {\n    return {\n      someState: 'hello pinia',\n    }\n  },\n  persist: {\n    storage: piniaPluginPersistedstate.sessionStorage(),\n  },\n})\n",[97,2669,2670,2680,2684,2702,2712,2718,2726,2730,2734,2738,2746,2750],{"__ignoreMap":99},[228,2671,2672,2674,2676,2678],{"class":230,"line":231},[228,2673,235],{"class":234},[228,2675,2251],{"class":238},[228,2677,242],{"class":234},[228,2679,259],{"class":245},[228,2681,2682],{"class":230,"line":249},[228,2683,828],{"emptyLinePlaceholder":827},[228,2685,2686,2688,2690,2692,2694,2696,2698,2700],{"class":230,"line":262},[228,2687,748],{"class":234},[228,2689,2266],{"class":234},[228,2691,2269],{"class":310},[228,2693,314],{"class":234},[228,2695,2274],{"class":317},[228,2697,370],{"class":238},[228,2699,2279],{"class":245},[228,2701,2282],{"class":238},[228,2703,2704,2706,2708,2710],{"class":230,"line":279},[228,2705,2287],{"class":317},[228,2707,2290],{"class":238},[228,2709,850],{"class":234},[228,2711,853],{"class":238},[228,2713,2714,2716],{"class":230,"line":285},[228,2715,858],{"class":234},[228,2717,853],{"class":238},[228,2719,2720,2722,2724],{"class":230,"line":298},[228,2721,2305],{"class":238},[228,2723,2308],{"class":245},[228,2725,914],{"class":238},[228,2727,2728],{"class":230,"line":304},[228,2729,1201],{"class":238},[228,2731,2732],{"class":230,"line":324},[228,2733,950],{"class":238},[228,2735,2736],{"class":230,"line":340},[228,2737,2437],{"class":238},[228,2739,2740,2742,2744],{"class":230,"line":352},[228,2741,2442],{"class":238},[228,2743,2664],{"class":317},[228,2745,2448],{"class":238},[228,2747,2748],{"class":230,"line":362},[228,2749,950],{"class":238},[228,2751,2752],{"class":230,"line":947},[228,2753,2089],{"class":238},[2558,2755,2756],{},[10,2757,2758,2760,2761,2764,2766],{},[97,2759,2664],{}," is client side only.",[2762,2763],"br",{},[97,2765,2664],{},"仅适用于客户端侧的数据存储。",[10,2768,2769,2770,24],{},"这和localStorage都是浏览器提供的web storage api ，用于在客户端存储键值对数据。它们的",[14,2771,2772],{},"核心区别在于数据的“有效期”和“作用域”",[10,2774,2775],{},"localStorage是永久有效期，是否手动清除，不然就不会消失，同源（协议+域名+端口）所有标签页窗口共享，sessionStorage似乎临时的同源或者一个ifname内共享，在浏览器重启之后会丢失，可以用于表单临时数据、本次会话的状态和一次性验证码。",[85,2777,2356],{"id":2356},[10,2779,2780,2781,2784,2785,2787],{},"该模块接受在 ",[97,2782,2783],{},"nuxt.config.ts"," 中定义的某些选项，这些选项属于 ",[97,2786,2352],{}," 键下的子键：",[161,2789,2790,2809,2814,2823],{},[41,2791,2792,2799,2800,2802,2803,2805,2806,2808],{},[1091,2793,2796],{"href":2794,"rel":2795},"https:\u002F\u002Fprazdevs.github.io\u002Fpinia-plugin-persistedstate\u002Fframeworks\u002Fnuxt.html#cookies",[1528],[97,2797,2798],{},"cookieOptions"," \n",[97,2801,2798],{}," （除了 ",[97,2804,2494],{}," 和 ",[97,2807,2486],{}," ，因为函数不支持这些编号）",[41,2810,2811],{},[97,2812,2813],{},"debug",[41,2815,2816],{},[1091,2817,2820],{"href":2818,"rel":2819},"https:\u002F\u002Fprazdevs.github.io\u002Fpinia-plugin-persistedstate\u002Fframeworks\u002Fnuxt.html#global-key",[1528],[97,2821,2822],{},"key",[41,2824,2825],{},[97,2826,2827],{},"storage",[10,2829,2830,2831,2834,2835,2838,2839,2838,2842,2845],{},"存储选项仅",[14,2832,2833],{},"接受预配置存储的字符串值","（ ",[97,2836,2837],{},"'cookies'"," 、 ",[97,2840,2841],{},"'localStorage'",[97,2843,2844],{},"'sessionStorage'"," ）。这是由于 Nuxt 传递模块选项到运行时的方式。",[90,2847,2849],{"className":222,"code":2848,"language":224,"meta":99,"style":99},"export default defineNuxtConfig({\n  modules: [\n    '@pinia\u002Fnuxt',\n    'pinia-plugin-persistedstate\u002Fnuxt'\n  ],\n  piniaPluginPersistedstate: {\n    storage: 'cookies',\n    cookieOptions: {\n      sameSite: 'lax',\n    },\n    debug: true,\n  },\n})\n",[97,2850,2851,2863,2868,2875,2880,2885,2890,2899,2904,2914,2919,2928,2932],{"__ignoreMap":99},[228,2852,2853,2855,2857,2860],{"class":230,"line":231},[228,2854,748],{"class":234},[228,2856,2034],{"class":234},[228,2858,2859],{"class":317}," defineNuxtConfig",[228,2861,2862],{"class":238},"({\n",[228,2864,2865],{"class":230,"line":249},[228,2866,2867],{"class":238},"  modules: [\n",[228,2869,2870,2873],{"class":230,"line":262},[228,2871,2872],{"class":245},"    '@pinia\u002Fnuxt'",[228,2874,914],{"class":238},[228,2876,2877],{"class":230,"line":279},[228,2878,2879],{"class":245},"    'pinia-plugin-persistedstate\u002Fnuxt'\n",[228,2881,2882],{"class":230,"line":285},[228,2883,2884],{"class":238},"  ],\n",[228,2886,2887],{"class":230,"line":298},[228,2888,2889],{"class":238},"  piniaPluginPersistedstate: {\n",[228,2891,2892,2895,2897],{"class":230,"line":304},[228,2893,2894],{"class":238},"    storage: ",[228,2896,2837],{"class":245},[228,2898,914],{"class":238},[228,2900,2901],{"class":230,"line":324},[228,2902,2903],{"class":238},"    cookieOptions: {\n",[228,2905,2906,2909,2912],{"class":230,"line":340},[228,2907,2908],{"class":238},"      sameSite: ",[228,2910,2911],{"class":245},"'lax'",[228,2913,914],{"class":238},[228,2915,2916],{"class":230,"line":352},[228,2917,2918],{"class":238},"    },\n",[228,2920,2921,2924,2926],{"class":230,"line":362},[228,2922,2923],{"class":238},"    debug: ",[228,2925,2239],{"class":310},[228,2927,914],{"class":238},[228,2929,2930],{"class":230,"line":947},[228,2931,950],{"class":238},[228,2933,2934],{"class":230,"line":953},[228,2935,2089],{"class":238},[85,2937,2938],{"id":2938},"全局秘钥",[10,2940,2941,2942,2945,2946,2949,2950,24],{},"我们可以提供一个模板字符串，用于",[14,2943,2944],{},"标记全局使用的键前缀\u002F后缀","。所提供的键必须包含令牌 ",[97,2947,2948],{},"%id"," ，该",[14,2951,2952],{},"令牌将被相应存储体的 ID 替代",[90,2954,2956],{"className":222,"code":2955,"language":224,"meta":99,"style":99},"export default defineNuxtConfig({\n  modules: [\n    '@pinia\u002Fnuxt',\n    'pinia-plugin-persistedstate\u002Fnuxt'\n  ],\n  piniaPluginPersistedstate: {\n    key: 'prefix_%id_postfix',\n  },\n})\n",[97,2957,2958,2968,2972,2978,2982,2986,2990,3000,3004],{"__ignoreMap":99},[228,2959,2960,2962,2964,2966],{"class":230,"line":231},[228,2961,748],{"class":234},[228,2963,2034],{"class":234},[228,2965,2859],{"class":317},[228,2967,2862],{"class":238},[228,2969,2970],{"class":230,"line":249},[228,2971,2867],{"class":238},[228,2973,2974,2976],{"class":230,"line":262},[228,2975,2872],{"class":245},[228,2977,914],{"class":238},[228,2979,2980],{"class":230,"line":279},[228,2981,2879],{"class":245},[228,2983,2984],{"class":230,"line":285},[228,2985,2884],{"class":238},[228,2987,2988],{"class":230,"line":298},[228,2989,2889],{"class":238},[228,2991,2992,2995,2998],{"class":230,"line":304},[228,2993,2994],{"class":238},"    key: ",[228,2996,2997],{"class":245},"'prefix_%id_postfix'",[228,2999,914],{"class":238},[228,3001,3002],{"class":230,"line":324},[228,3003,950],{"class":238},[228,3005,3006],{"class":230,"line":340},[228,3007,2089],{"class":238},[10,3009,3010,3011,3014,3015,3018,3019,3022,3023,24],{},"任何以 ",[97,3012,3013],{},"my-store"," 作为持久化键的store（无论是用户提供的还是从store ID 推断出来的），都会被保存在 ",[97,3016,3017],{},"prefix_my-store_postfix"," 这个键下。在nuxt的集成中，global 是一个",[14,3020,3021],{},"全局的前缀\u002F命名空间","，用来",[14,3024,3025],{},"区分不同应用或环境的存储数据",[10,3027,3028,3029,3032,3033,3036,3037,3039,3040,3043],{},"为所有持久化的 Store 状态",[14,3030,3031],{},"添加一个全局前缀","，避免",[14,3034,3035],{},"多个应用","共享同一个 ",[97,3038,2570],{}," 时发生",[14,3041,3042],{},"键名冲突","。Global Key 只在客户端存储生效，服务端不影响",[10,3045,3046],{},"example:",[90,3048,3050],{"className":222,"code":3049,"language":224,"meta":99,"style":99},"\u002F\u002F nuxt.config.ts\nexport default defineNuxtConfig({\n  modules: [\n    '@pinia\u002Fnuxt',\n    'pinia-plugin-persistedstate\u002Fnuxt'\n  ],\n  piniaPersistedstate: {\n    key: 'my-app-v1',        \u002F\u002F ✅ Global Key\n    storage: 'localStorage'  \u002F\u002F 默认\n  }\n})\n\n\n\u002F\u002F 没有 global key\nlocalStorage.getItem('userStore')   \u002F\u002F { name: 'Alice' }\n\u002F\u002F 有 global key\nlocalStorage.getItem('my-app-v1:userStore')   \u002F\u002F { name: 'Alice' }\n",[97,3051,3052,3057,3067,3071,3077,3081,3085,3090,3103,3112,3116,3120,3124,3128,3133,3152,3157],{"__ignoreMap":99},[228,3053,3054],{"class":230,"line":231},[228,3055,3056],{"class":275},"\u002F\u002F nuxt.config.ts\n",[228,3058,3059,3061,3063,3065],{"class":230,"line":249},[228,3060,748],{"class":234},[228,3062,2034],{"class":234},[228,3064,2859],{"class":317},[228,3066,2862],{"class":238},[228,3068,3069],{"class":230,"line":262},[228,3070,2867],{"class":238},[228,3072,3073,3075],{"class":230,"line":279},[228,3074,2872],{"class":245},[228,3076,914],{"class":238},[228,3078,3079],{"class":230,"line":285},[228,3080,2879],{"class":245},[228,3082,3083],{"class":230,"line":298},[228,3084,2884],{"class":238},[228,3086,3087],{"class":230,"line":304},[228,3088,3089],{"class":238},"  piniaPersistedstate: {\n",[228,3091,3092,3094,3097,3100],{"class":230,"line":324},[228,3093,2994],{"class":238},[228,3095,3096],{"class":245},"'my-app-v1'",[228,3098,3099],{"class":238},",        ",[228,3101,3102],{"class":275},"\u002F\u002F ✅ Global Key\n",[228,3104,3105,3107,3109],{"class":230,"line":340},[228,3106,2894],{"class":238},[228,3108,2841],{"class":245},[228,3110,3111],{"class":275},"  \u002F\u002F 默认\n",[228,3113,3114],{"class":230,"line":352},[228,3115,1683],{"class":238},[228,3117,3118],{"class":230,"line":362},[228,3119,2089],{"class":238},[228,3121,3122],{"class":230,"line":947},[228,3123,828],{"emptyLinePlaceholder":827},[228,3125,3126],{"class":230,"line":953},[228,3127,828],{"emptyLinePlaceholder":827},[228,3129,3130],{"class":230,"line":1116},[228,3131,3132],{"class":275},"\u002F\u002F 没有 global key\n",[228,3134,3135,3138,3141,3143,3146,3149],{"class":230,"line":1121},[228,3136,3137],{"class":238},"localStorage.",[228,3139,3140],{"class":317},"getItem",[228,3142,370],{"class":238},[228,3144,3145],{"class":245},"'userStore'",[228,3147,3148],{"class":238},")   ",[228,3150,3151],{"class":275},"\u002F\u002F { name: 'Alice' }\n",[228,3153,3154],{"class":230,"line":1127},[228,3155,3156],{"class":275},"\u002F\u002F 有 global key\n",[228,3158,3159,3161,3163,3165,3168,3170],{"class":230,"line":1143},[228,3160,3137],{"class":238},[228,3162,3140],{"class":317},[228,3164,370],{"class":238},[228,3166,3167],{"class":245},"'my-app-v1:userStore'",[228,3169,3148],{"class":238},[228,3171,3151],{"class":275},[10,3173,3174,3175,3177,3178,3181,3182,3185,3186,3188,3189,3191],{},"虽然在中间件内部访问store是可行的，但从 ",[97,3176,2445],{}," 持久化\u002F存储数据时可能会出现问题，并导致 ",[97,3179,3180],{},"[nuxt] A composable that requires access to the Nuxt instance was called outside of a plugin, Nuxt hook, Nuxt middleware, or Vue setup function."," 错误。这是因为 Pinia 存储在 ",[14,3183,3184],{},"Nuxt 实例之前就已经被实例化","，而 ",[97,3187,2119],{}," 则需要 Nuxt 实例才能访问 ",[97,3190,2465],{}," 。",[10,3193,3194],{},"为了克服这个限制，你可以采取以下方法：",[10,3196,3197],{},"在 Nuxt 实例可用之后，务必访问该商店。需要注意的是，要考虑到中间件的使用问题。",[10,3199,3200,3201,3203],{},"在这种特定情况下，可以直接使用 ",[97,3202,2465],{}," 可组合对象，而不是使用存储系统。",[33,3205,3206],{"id":3206},"更多高级用法",[85,3208,3209],{"id":3209},"每个store配置多个数据持久化",[10,3211,3212,3213,2235,3216,3218],{},"在某些特定情况下，您可能需要将来自单个存储的数据持久化到不同的存储。 ",[97,3214,3215],{}," ",[97,3217,3215],{}," 选项也接受一个配置数组。",[90,3220,3222],{"className":222,"code":3221,"language":224,"meta":99,"style":99},"import { defineStore } from 'pinia'\n\ndefineStore('store', {\n  state: () => ({\n    toLocal: '',\n    toSession: '',\n    toNowhere: '',\n  }),\n  persist: [\n    {\n      pick: ['toLocal'],\n      storage: localStorage,\n    },\n    {\n      pick: ['toSession'],\n      storage: sessionStorage,\n    },\n  ],\n})\n",[97,3223,3224,3234,3238,3249,3259,3269,3278,3287,3292,3297,3302,3313,3318,3322,3326,3335,3340,3344,3348],{"__ignoreMap":99},[228,3225,3226,3228,3230,3232],{"class":230,"line":231},[228,3227,235],{"class":234},[228,3229,2251],{"class":238},[228,3231,242],{"class":234},[228,3233,259],{"class":245},[228,3235,3236],{"class":230,"line":249},[228,3237,828],{"emptyLinePlaceholder":827},[228,3239,3240,3242,3244,3247],{"class":230,"line":262},[228,3241,1693],{"class":317},[228,3243,370],{"class":238},[228,3245,3246],{"class":245},"'store'",[228,3248,2282],{"class":238},[228,3250,3251,3253,3255,3257],{"class":230,"line":279},[228,3252,2287],{"class":317},[228,3254,2290],{"class":238},[228,3256,850],{"class":234},[228,3258,874],{"class":238},[228,3260,3261,3264,3267],{"class":230,"line":285},[228,3262,3263],{"class":238},"    toLocal: ",[228,3265,3266],{"class":245},"''",[228,3268,914],{"class":238},[228,3270,3271,3274,3276],{"class":230,"line":298},[228,3272,3273],{"class":238},"    toSession: ",[228,3275,3266],{"class":245},[228,3277,914],{"class":238},[228,3279,3280,3283,3285],{"class":230,"line":304},[228,3281,3282],{"class":238},"    toNowhere: ",[228,3284,3266],{"class":245},[228,3286,914],{"class":238},[228,3288,3289],{"class":230,"line":324},[228,3290,3291],{"class":238},"  }),\n",[228,3293,3294],{"class":230,"line":340},[228,3295,3296],{"class":238},"  persist: [\n",[228,3298,3299],{"class":230,"line":352},[228,3300,3301],{"class":238},"    {\n",[228,3303,3304,3307,3310],{"class":230,"line":362},[228,3305,3306],{"class":238},"      pick: [",[228,3308,3309],{"class":245},"'toLocal'",[228,3311,3312],{"class":238},"],\n",[228,3314,3315],{"class":230,"line":947},[228,3316,3317],{"class":238},"      storage: localStorage,\n",[228,3319,3320],{"class":230,"line":953},[228,3321,2918],{"class":238},[228,3323,3324],{"class":230,"line":1116},[228,3325,3301],{"class":238},[228,3327,3328,3330,3333],{"class":230,"line":1121},[228,3329,3306],{"class":238},[228,3331,3332],{"class":245},"'toSession'",[228,3334,3312],{"class":238},[228,3336,3337],{"class":230,"line":1127},[228,3338,3339],{"class":238},"      storage: sessionStorage,\n",[228,3341,3342],{"class":230,"line":1143},[228,3343,2918],{"class":238},[228,3345,3346],{"class":230,"line":1157},[228,3347,2884],{"class":238},[228,3349,3350],{"class":230,"line":1163},[228,3351,2089],{"class":238},[10,3353,3354,3355,3358,3359,3361,3362,3365,3366,3368,3369,3372],{},"在这个示例中， ",[97,3356,3357],{},"toLocal"," 的值会被保留在 ",[97,3360,2570],{}," 中，而 ",[97,3363,3364],{},"toSession"," 的值则会被保留在 ",[97,3367,2664],{}," 中。 ",[97,3370,3371],{},"toNowhere"," 的值则不会被保留。",[2558,3374,3375],{},[10,3376,3377,3379,3380,3383],{},[228,3378,2564],{}," 在未指定 ",[97,3381,3382],{},"paths"," 选项，或者两个持久化配置中目标路径相同的情况下，请务必小心操作。这可能导致数据不一致的问题。在重新 hydration 过程中，持久化操作将按照声明顺序进行执行。",[85,3385,3386],{"id":3386},"水合",[10,3388,3389,3390,2805,3393,3396],{},"如果你需要手动触发从存储中读取数据的过程，每个存储接口现在都提供了一个相关的方法。默认情况下，调用此方法还会触发 ",[97,3391,3392],{},"beforeHydrate",[97,3394,3395],{},"afterHydrate"," 这两个钩子函数。如果你不想触发这些钩子，可以指定不调用这些方法。",[90,3398,3400],{"className":222,"code":3399,"language":224,"meta":99,"style":99},"import { defineStore } from 'pinia'\n\nconst useStore = defineStore('store', {\n  state: () => ({\n    someData: 'Hello Pinia'\n  })\n})\n",[97,3401,3402,3412,3416,3432,3442,3450,3455],{"__ignoreMap":99},[228,3403,3404,3406,3408,3410],{"class":230,"line":231},[228,3405,235],{"class":234},[228,3407,2251],{"class":238},[228,3409,242],{"class":234},[228,3411,259],{"class":245},[228,3413,3414],{"class":230,"line":249},[228,3415,828],{"emptyLinePlaceholder":827},[228,3417,3418,3420,3422,3424,3426,3428,3430],{"class":230,"line":262},[228,3419,307],{"class":234},[228,3421,2269],{"class":310},[228,3423,314],{"class":234},[228,3425,2274],{"class":317},[228,3427,370],{"class":238},[228,3429,3246],{"class":245},[228,3431,2282],{"class":238},[228,3433,3434,3436,3438,3440],{"class":230,"line":279},[228,3435,2287],{"class":317},[228,3437,2290],{"class":238},[228,3439,850],{"class":234},[228,3441,874],{"class":238},[228,3443,3444,3447],{"class":230,"line":285},[228,3445,3446],{"class":238},"    someData: ",[228,3448,3449],{"class":245},"'Hello Pinia'\n",[228,3451,3452],{"class":230,"line":298},[228,3453,3454],{"class":238},"  })\n",[228,3456,3457],{"class":230,"line":304},[228,3458,2089],{"class":238},[10,3460,3461],{},"比如说这个store， 你可以调用$hydrate",[90,3463,3465],{"className":222,"code":3464,"language":224,"meta":99,"style":99},"const store = useStore()\nstore.$hydrate({ runHooks: false })\n",[97,3466,3467,3480],{"__ignoreMap":99},[228,3468,3469,3471,3474,3476,3478],{"class":230,"line":231},[228,3470,307],{"class":234},[228,3472,3473],{"class":310}," store",[228,3475,314],{"class":234},[228,3477,2269],{"class":317},[228,3479,337],{"class":238},[228,3481,3482,3485,3488,3491,3494],{"class":230,"line":249},[228,3483,3484],{"class":238},"store.",[228,3486,3487],{"class":317},"$hydrate",[228,3489,3490],{"class":238},"({ runHooks: ",[228,3492,3493],{"class":310},"false",[228,3495,3496],{"class":238}," })\n",[10,3498,3499],{},"这将从存储中获取数据，并将其应用到当前状态。在上述示例中，钩子不会被触发如果需要手动触发持久化到存储，现在每个存储都暴露了一个。",[10,3501,3502,3503,3505,3506,3508],{},"如果需要手动触发持久化到存储，现在每个存储都暴露了一个 ",[97,3504,3215],{},"$persist",[97,3507,3215],{}," 方法。",[90,3510,3511],{"className":222,"code":3399,"language":224,"meta":99,"style":99},[97,3512,3513,3523,3527,3543,3553,3559,3563],{"__ignoreMap":99},[228,3514,3515,3517,3519,3521],{"class":230,"line":231},[228,3516,235],{"class":234},[228,3518,2251],{"class":238},[228,3520,242],{"class":234},[228,3522,259],{"class":245},[228,3524,3525],{"class":230,"line":249},[228,3526,828],{"emptyLinePlaceholder":827},[228,3528,3529,3531,3533,3535,3537,3539,3541],{"class":230,"line":262},[228,3530,307],{"class":234},[228,3532,2269],{"class":310},[228,3534,314],{"class":234},[228,3536,2274],{"class":317},[228,3538,370],{"class":238},[228,3540,3246],{"class":245},[228,3542,2282],{"class":238},[228,3544,3545,3547,3549,3551],{"class":230,"line":279},[228,3546,2287],{"class":317},[228,3548,2290],{"class":238},[228,3550,850],{"class":234},[228,3552,874],{"class":238},[228,3554,3555,3557],{"class":230,"line":285},[228,3556,3446],{"class":238},[228,3558,3449],{"class":245},[228,3560,3561],{"class":230,"line":298},[228,3562,3454],{"class":238},[228,3564,3565],{"class":230,"line":304},[228,3566,2089],{"class":238},[10,3568,3569],{},"你可以调用$persist",[90,3571,3573],{"className":222,"code":3572,"language":224,"meta":99,"style":99},"const store = useStore()\nstore.$persist()\n",[97,3574,3575,3587],{"__ignoreMap":99},[228,3576,3577,3579,3581,3583,3585],{"class":230,"line":231},[228,3578,307],{"class":234},[228,3580,3473],{"class":310},[228,3582,314],{"class":234},[228,3584,2269],{"class":317},[228,3586,337],{"class":238},[228,3588,3589,3591,3593],{"class":230,"line":249},[228,3590,3484],{"class":238},[228,3592,3505],{"class":317},[228,3594,337],{"class":238},[10,3596,3597,3599,3600,3602],{},[97,3598,2119],{}," 对 SSR（服务端渲染）的支持，核心机制是“客户端优先”，即插件会避免在服务端执行存储读写，防止因访问 ",[97,3601,2570],{}," 导致应用报错，同时确保客户端激活（Hydration）时数据一致。",[3604,3605,3606],"style",{},"html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}",{"title":99,"searchDepth":249,"depth":249,"links":3608},[3609,3610,3611,3612,3613,3627],{"id":35,"depth":262,"text":36},{"id":82,"depth":262,"text":83},{"id":149,"depth":262,"text":150},{"id":185,"depth":262,"text":186},{"id":216,"depth":249,"text":216,"children":3614},[3615,3616,3617,3619,3621,3623,3624,3625,3626],{"id":395,"depth":262,"text":395},{"id":407,"depth":262,"text":407},{"id":454,"depth":262,"text":3618},"1. 组件状态 vs 全局状态管理",{"id":495,"depth":262,"text":3620},"2. 何时使用 Hook，何时使用 Pinia",{"id":537,"depth":262,"text":3622},"3. 代码结构和维护性",{"id":556,"depth":262,"text":557},{"id":626,"depth":262,"text":626},{"id":677,"depth":262,"text":678},{"id":729,"depth":262,"text":729},{"id":781,"depth":249,"text":781,"children":3628},[3629,3630,3631,3632],{"id":643,"depth":262,"text":643},{"id":1512,"depth":262,"text":1512},{"id":2092,"depth":262,"text":2092},{"id":3206,"depth":262,"text":3206},"​\tPinia 是 Vue 3 官方推荐的状态管理库，它是 Vuex 的继任者，专门为 Vue 3 设计。Pinia 提供了一个更加简洁、直观、功能强大的方式来管理和共享应用中的状态（数据）。","md",{},"\u002Fvue\u002Fpinia",{"description":3633},"Vue\u002FPinia","IaC9Wbd5D0bZh9SqLMoJ7Q1g_Ehh7pee_685pmoGvak",1791042467749]