PageSourceSearch

https://johnnywang1994.github.io/book/assets/pinia-intro.html-8UzTQKcY.js

js johnnywang1994.github.io collected 2026-10-03 09:25:43 UTC 80,685 bytes, 309 lines download raw bytes

1import{_ as e,c as t,b as s,a as p,e as c,r as o,o as i}from"./app-BgYE7jZN.js";const l={};function u(r,n){const a=o("SocialBlock");return i(),t("div",null,[n[0]||(n[0]=s("h1",{id:"pinia-vuex-的後繼者",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#pinia-vuex-的後繼者"},[s("span",null,"Pinia - Vuex 的後繼者")])],-1)),p(a,{hashtags:"vuejs3, pinia"}),n[1]||(n[1]=c(`<p>大家好,今天要來介紹一款 Vue 的 State Management 套件 - <a href="https://pinia.esm.dev/" target="_blank" rel="noopener noreferrer">Pinia</a>,即將在不久的將來(或是已經)能夠取代 Vuex,為何這麼說呢?</p><h2 id="pinia-vs-vuex" tabindex="-1"><a class="header-anchor" href="#pinia-vs-vuex"><span>Pinia vs. Vuex</span></a></h2><p>首先可以看看 <a href="https://pinia.esm.dev/introduction.html#comparison-with-vuex-3-x-4-x" target="_blank" rel="noopener noreferrer">Pinia 官網對比 Vuex</a> 的簡要敘述如下</p><ul><li>移除 Mutations</li><li>Typescript 不再需要多餘的 types 來包裝</li><li>不再需要引入各種 magic string,直接引入函數,享受自動補全帶來的快樂</li><li>不再需要動態註冊模組,預設都是動態註冊</li><li>拋棄 Nested Module,在保持模組互相引入的前提下,採用 Flat Module,甚至可以進行 <code>circular dependencies</code> 讓兩模組互相調用(需注意可能產生無限迴圈)</li><li>無需 namespaced,所有模組都已自動 namespaced</li></ul><p>看到這是不是很興奮!長久以來被詬病的 mutations 居然移除拉~其實作者就是經過多方的用戶回饋後決定這些改動,接下來一起來看看具體該怎麼用吧</p><h2 id="install" tabindex="-1"><a class="header-anchor" href="#install"><span>Install</span></a></h2><ol><li>安裝 pinia</li></ol><div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh"><pre><code class="language-bash"><span class="line">$ <span class="token function">yarn</span> <span class="token function">add</span> pinia</span>
2<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div></div></div><ol start="2"><li>創建 pinia</li></ol><p>與 Vuex 不同,因為 pinia 是預設動態創建模組,我們可以先註冊完 app 後再來寫模組具體內容</p><p><strong>store/index.js</strong></p><div class="language-javascript line-numbers-mode" data-highlighter="prismjs" data-ext="js"><pre><code class="language-javascript"><span class="line"><span class="token keyword">import</span> <span class="token punctuation">{</span> createPinia <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&#39;pinia&#39;</span><span class="token punctuation">;</span></span>
3<span class="line"></span>
4<span class="line"><span class="token comment">// 創建 pinia</span></span>
5<span class="line"><span class="token keyword">const</span> pinia <span class="token operator">=</span> <span class="token function">createPinia</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
6<span class="line"></span>
7<span class="line"><span class="token keyword">export</span> <span class="token keyword">default</span> pinia<span class="token punctuation">;</span></span>
8<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><blockquote><p>需注意,Vue2 使用時需要額外引入 <code>PiniaVuePlugin</code>,具體如下</p></blockquote><div class="language-javascript line-numbers-mode" data-highlighter="prismjs" data-ext="js"><pre><code class="language-javascript"><span class="line"><span class="token keyword">import</span> <span class="token punctuation">{</span> createPinia<span class="token punctuation">,</span> PiniaVuePlugin <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&#39;pinia&#39;</span><span class="token punctuation">;</span></span>
9<span class="line"></span>
10<span class="line">Vue<span class="token punctuation">.</span><span class="token function">
10use</span><span class="token punctuation">(</span>PiniaVuePlugin<span class="token punctuation">)</span><span class="token punctuation">;</span></span>
11<span class="line"><span class="token keyword">const</span> pinia <span class="token operator">=</span> <span class="token function">createPinia</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
12<span class="line"></span>
13<span class="line"><span class="token keyword">export</span> <span class="token keyword">default</span> pinia<span class="token punctuation">;</span></span>
14<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><blockquote><p>另外如果你的 Vue2 底層是使用 webpack 的話,需要在 module 的 rules 裏添加如下規則,否則會出現 esmodule 引入的錯誤,詳細可<a href="https://github.com/polkadot-js/extension/issues/621#issuecomment-759341776" target="_blank" rel="noopener noreferrer">參考這邊討論</a></p></blockquote><div class="language-javascript line-numbers-mode" data-highlighter="prismjs" data-ext="js"><pre><code class="language-javascript"><span class="line">module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">{</span></span>
15<span class="line">  <span class="token literal-property property">module</span><span class="token operator">:</span> <span class="token punctuation">{</span></span>
16<span class="line">    <span class="token literal-property property">rules</span><span class="token operator">:</span> <span class="token punctuation">[</span></span>
17<span class="line">      <span class="token comment">// FIX: Can’t import the named export &#39;XXX&#39; from non EcmaScript module</span></span>
18<span class="line">      <span class="token punctuation">{</span></span>
19<span class="line">        <span class="token literal-property property">test</span><span class="token operator">:</span> <span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">\\.mjs$</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">,</span></span>
20<span class="line">        <span class="token literal-property property">include</span><span class="token operator">:</span> <span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">node_modules</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">,</span></span>
21<span class="line">        <span class="token literal-property property">type</span><span class="token operator">:</span> <span class="token string">&#39;javascript/auto&#39;</span><span class="token punctuation">,</span></span>
22<span class="line">      <span class="token punctuation">}</span><span class="token punctuation">,</span></span>
23<span class="line">    <span class="token punctuation">]</span></span>
24<span class="line">  <span class="token punctuation">}</span></span>
25<span class="line"><span class="token punctuation">}</span></span>
26<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p><strong>main.js</strong></p><div class="language-javascript line-numbers-mode" data-highlighter="prismjs" data-ext="js"><pre><code class="language-javascript"><span class="line"><span class="token keyword">
26import</span> <span class="token punctuation">{</span> createApp <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&#39;vue&#39;</span><span class="token punctuation">;</span></span>
27<span class="line"><span class="token keyword">import</span> App <span class="token keyword">from</span> <span class="token string">&#39;./App.vue&#39;</span><span class="token punctuation">;</span></span>
28<span class="line"><span class="token keyword">import</span> pinia <span class="token keyword">from</span> <span class="token string">&#39;./store&#39;</span><span class="token punctuation">;</span></span>
29<span class="line"></span>
30<span class="line"><span class="token keyword">const</span> app <span class="token operator">=</span> <span class="token function">createApp</span><span class="token punctuation">(</span>App<span class="token punctuation">)</span><span class="token punctuation">;</span></span>
31<span class="line"></span>
32<span class="line"><span class="token comment">// 綁定 pinia 到 app</span></span>
33<span class="line">app<span class="token punctuation">.</span><span class="token function">use</span><span class="token punctuation">(</span>pinia<span class="token punctuation">)</span><span class="token punctuation">;</span></span>
34<span class="line"></span>
35<span class="line">app<span class="token punctuation">.</span><span class="token function">mount</span><span class="token punctuation">(</span><span class="token string">&#39;#app&#39;</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
36<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>Vue2 註冊方式則跟 vuex 相同</p><div class="language-javascript line-numbers-mode" data-highlighter="prismjs" data-ext="js"><pre><code class="language-javascript"><span class="line"><span class="token keyword">import</span> Vue <span class="token keyword">from</span> <span class="token string">&#39;vue&#39;</span><span class="token punctuation">;</span></span>
37<span class="line"><span class="token keyword">import</span> App <span class="token keyword">from</span> <span class="token string">&#39;./App.vue&#39;</span><span class="token punctuation">;</span></span>
38<span class="line"><span class="token keyword">import</span> pinia <span class="token keyword">from</span> <span class="token string">&#39;./store&#39;</span><span class="token punctuation">;</span></span>
39<span class="line"></span>
40<span class="line"><span class="token keyword">new</span> <span class="token class-name">Vue</span><span class="token punctuation">(</span><span class="token punctuation">{</span></span>
41<span class="line">  pinia<span class="token punctuation">,</span></span>
42<span class="line">  <span class="token function-variable function">render</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token parameter">h</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token function">h</span><span class="token punctuation">(</span>App<span class="token punctuation">)</span><span class="token punctuation">,</span></span>
43<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">$mount</span><span class="token punctuation">(</span><span class="token string">&#39;#app&#39;</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
44<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><ol start="3"><li>創建 Module</li></ol><p>引入 <code>defineStore</code> 方法,Options 與 Vuex 除了 mutations 以外基本相同,包含 <code>state</code>, <code>getters</code>, <code>actions</code></p><p><strong>store/main.js</strong></p><div class="language-javascript line-numbers-mode" data-highlighter="prismjs" data-ext="js"><pre><code class="language-javascript"><span class="line"><span class="token keyword">
44import</span> <span class="token punctuation">{</span> defineStore <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&#39;pinia&#39;</span><span class="token punctuation">;</span></span>
45<span class="line"></span>
46<span class="line"><span class="token comment">// 這邊 defineStore 會自動動態註冊模組,回傳值為 hook function</span></span>
47<span class="line"><span class="token keyword">export</span> <span class="token keyword">const</span> useStore <span class="token operator">=</span> <span class="token function">defineStore</span><span class="token punctuation">(</span><span class="token string">&#39;Main&#39;</span><span class="token punctuation">,</span> <span class="token punctuation">{</span></span>
48<span class="line">  <span class="token comment">// 注意 state 是一個 function,推薦使用 arrow function</span></span>
49<span class="line">  <span class="token comment">// 可幫助 typescript 更好進行類型推斷</span></span>
50<span class="line">  <span class="token function-variable function">state</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span><span class="token punctuation">{</span></span>
51<span class="line">    <span class="token literal-property property">APILoading</span><span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span></span>
52<span class="line">    <span class="token literal-property property">counter</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span></span>
53<span class="line">  <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
54<span class="line">  <span class="token literal-property property">getters</span><span class="token operator">:</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span></span>
55<span class="line">  <span class="token literal-property property">actions</span><span class="token operator">:</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span></span>
56<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span></span>
57<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="usage-組件內使用" tabindex="-1"><a class="header-anchor" href="#usage-組件內使用"><span>Usage 組件內使用</span></a></h2><p>這邊先以 vue3 為使用範例</p><h3 id="state" tabindex="-1"><a class="header-anchor" href="#state"><span>State</span></a></h3><p><strong>App.vue</strong></p><div class="language-javascript line-numbers-mode" data-highlighter="prismjs" data-ext="js"><pre><code class="language-javascript"><span class="line"><span class="token comment">// 引入 defineStore 回傳的 hook</span></span>
58<span class="line"><span class="token keyword">import</span> <span class="token punctuation">{</span> useStore <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&#39;./store/main&#39;</span><span class="token punctuation">;</span></span>
59<span class="line"></span>
60<span class="line"><span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span></span>
61<span class="line">  <span class="token function">setup</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
62<span class="line">    <span class="token comment">// store 物件是 reactive,注意不可直接解構</span></span>
63<span class="line">    <span class="token keyword">const</span> store <span class="token operator">=</span> <span class="token function">useStore</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
64<span class="line"></span>
65<span class="line">    <span class="token keyword">return</span> <span class="token punctuation">{</span></span>
66<span class="line">      store<span class="token punctuation">,</span></span>
67<span class="line">    <span class="token punctuation">}</span><span class="token punctuation">;</span></span>
68<span class="line">  <span class="token punctuation">}</span><span class="token punctuation">,</span></span>
69<span class="line"><span class="token punctuation">}</span></span>
70<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="解構-store" tabindex="-1"><a class="header-anchor" href="#解構-store"><span><strong>解構 store</strong></span></a></h4><p>因為 store 是個 reactive 物件,如果需要解構,可使用 <code>storeToRefs</code> 進行解構</p><div class="language-javascript line-numbers-mode" data-highlighter="prismjs" data-ext="js"><pre><code class="language-javascript"><span class="line"><span class="token keyword">
70import</span> <span class="token punctuation">{</span> storeToRefs <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&#39;pinia&#39;</span><span class="token punctuation">;</span></span>
71<span class="line"><span class="token keyword">import</span> <span class="token punctuation">{</span> useStore <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&#39;./store/main&#39;</span><span class="token punctuation">;</span></span>
72<span class="line"></span>
73<span class="line"><span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span></span>
74<span class="line">  <span class="token function">setup</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
75<span class="line">    <span class="token keyword">const</span> store <span class="token operator">=</span> <span class="token function">useStore</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
76<span class="line"></span>
77<span class="line">    <span class="token comment">// refs</span></span>
78<span class="line">    <span class="token keyword">const</span> <span class="token punctuation">{</span> APILoading <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token function">storeToRefs</span><span class="token punctuation">(</span>store<span class="token punctuation">)</span><span class="token punctuation">;</span></span>
79<span class="line"></span>
80<span class="line">    <span class="token keyword">return</span> <span class="token punctuation">{</span></span>
81<span class="line">      APILoading<span class="token punctuation">,</span></span>
82<span class="line">    <span class="token punctuation">}</span><span class="token punctuation">;</span></span>
83<span class="line">  <span class="token punctuation">}</span><span class="token punctuation">,</span></span>
84<span class="line"><span class="token punctuation">}</span></span>
85<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="options-api-support" tabindex="-1"><a class="header-anchor" href="#options-api-support"><span><strong>Options API Support</strong></span></a></h4><p>引入 <code>mapState</code> 可以像 Vuex 一樣註冊到 options API,但不用 magic string,而是注入 hook function 即可</p><div class="language-javascript line-numbers-mode" data-highlighter="prismjs" data-ext="js"><pre><code class="language-javascript"><span class="line"><span class="token keyword">import</span> <span class="token punctuation">{</span> mapState <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&#39;pinia&#39;</span><span class="token punctuation">;</span></span>
86<span class="line"><span class="token comment">// 引入 hook</span></span>
87<span class="line"><span class="token keyword">import</span> <span class="token punctuation">{</span> useStore <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&#39;./store/main&#39;</span><span class="token punctuation">;</span></span>
88<span class="line"></span>
89<span class="line"><span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span></span>
90<span class="line">  <span class="token literal-property property">computed</span><span class="token operator">:</span> <span class="token punctuation">{</span></span>
91<span class="line">    <span class="token comment">// 可透過 this.counter 取得狀態</span></span>
92<span class="line">    <span class="token operator">...</span><span class="token function">mapState</span><span class="token punctuation">(</span>useStore<span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">&#39;counter&#39;</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
93<span class="line">    <span class="token comment">// 與上方相同,但註冊為 this.storeCounter</span></span>
94<span class="line">    <span class="token operator">...</span><span class="token function">mapState</span><span class="token punctuation">(</span>useStore<span class="token punctuation">,</span> <span class="token punctuation">{</span></span>
95<span class="line">
95      <span class="token literal-property property">storeCounter</span><span class="token operator">:</span> <span class="token string">&#39;counter&#39;</span><span class="token punctuation">,</span></span>
96<span class="line">      <span class="token comment">// 也可以 function 直接取得 store 進行複雜處理</span></span>
97<span class="line">      <span class="token function-variable function">double</span><span class="token operator">:</span> <span class="token parameter">store</span> <span class="token operator">=&gt;</span> store<span class="token punctuation">.</span>counter <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">,</span></span>
98<span class="line">      <span class="token comment">// 一樣可正確註冊,但 typescript 會無法正確自動推斷類型</span></span>
99<span class="line">      <span class="token function">magicValue</span><span class="token punctuation">(</span><span class="token parameter">store</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
100<span class="line">        <span class="token keyword">return</span> store<span class="token punctuation">.</span>someGetter <span class="token operator">+</span> <span class="token keyword">this</span><span class="token punctuation">.</span>counter <span class="token operator">+</span> <span class="token keyword">this</span><span class="token punctuation">.</span>double<span class="token punctuation">;</span></span>
101<span class="line">      <span class="token punctuation">}</span><span class="token punctuation">,</span></span>
102<span class="line">    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
103<span class="line">  <span class="token punctuation">}</span><span class="token punctuation">,</span></span>
104<span class="line"><span class="token punctuation">}</span><span class="token punctuation">;</span></span>
105<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>如果需要可在 store 外部改變 state 時(例如你在做表單),可以使用 <code>mapWritableState</code>,但無法使用 function 的方式註冊</p><div class="language-javascript line-numbers-mode" data-highlighter="prismjs" data-ext="js"><pre><code class="language-javascript"><span class="line"><span class="token keyword">import</span> <span class="token punctuation">{</span> mapWritableState <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&#39;pinia&#39;</span><span class="token punctuation">;</span></span>
106<span class="line"><span class="token keyword">import</span> <span class="token punctuation">{</span> useStore <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&#39;./store/main&#39;</span><span class="token punctuation">;</span></span>
107<span class="line"></span>
108<span class="line"><span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span></span>
109<span class="line">  <span class="token literal-property property">computed</span><span class="token operator">:</span> <span class="token punctuation">{</span></span>
110<span class="line">    <span class="token comment">// this.counter++</span></span>
111<span class="line">    <span class="token operator">...</span><span class="token function">mapWritableState</span><span class="token punctuation">(</span>useStore<span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">&#39;counter&#39;</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
112<span class="line">  <span class="token punctuation">}</span><span class="token punctuation">,</span></span>
113<span class="line"><span class="token punctuation">}</span><span class="token punctuation">;</span></span>
114<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="patch-改動狀態" tabindex="-1"><a class="header-anchor" href="#patch-改動狀態"><span>$patch 改動狀態</span></a></h4><p>比起直接修改狀態,也可以透過 $patch 統一進行狀態修改</p><div class="language-javascript line-numbers-mode" data-highlighter="prismjs" data-ext="js"><pre><code class="language-javascript"><span class="line">store<span class="token punctuation">.</span><span class="token function">$patch</span><span class="token punctuation">(</span><span class="token punctuation">{</span></span>
115<span class="line">  <span class="token literal-property property">counter</span><span class="token operator">:</span> store<span class="token punctuation">.</span>counter <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">,</span></span>
116<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span></span>
117<span class="line"><span class="token comment">// or</span></span>
118<span class="line">store<span class="token punctuation">.</span><span class="token function">$patch</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">state</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span></span>
119<span class="line">
119  state<span class="token punctuation">.</span>counter <span class="token operator">+=</span> <span class="token number">1</span><span class="token punctuation">;</span></span>
120<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span></span>
121<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="getters" tabindex="-1"><a class="header-anchor" href="#getters"><span>Getters</span></a></h3><p>getters 與 Vuex 相同,第一個 args 為 state</p><div class="language-javascript line-numbers-mode" data-highlighter="prismjs" data-ext="js"><pre><code class="language-javascript"><span class="line"><span class="token keyword">export</span> <span class="token keyword">const</span> useStore <span class="token operator">=</span> <span class="token function">defineStore</span><span class="token punctuation">(</span><span class="token string">&#39;main&#39;</span><span class="token punctuation">,</span> <span class="token punctuation">{</span></span>
122<span class="line">  <span class="token function-variable function">state</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span><span class="token punctuation">{</span></span>
123<span class="line">    <span class="token literal-property property">counter</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span></span>
124<span class="line">  <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
125<span class="line">  <span class="token literal-property property">getters</span><span class="token operator">:</span> <span class="token punctuation">{</span></span>
126<span class="line">    <span class="token comment">// 可用箭頭函數</span></span>
127<span class="line">    <span class="token function-variable function">doubleCount</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token parameter">state</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> state<span class="token punctuation">.</span>counter <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">,</span></span>
128<span class="line">    <span class="token comment">// this 指向 store 本身</span></span>
129<span class="line">    <span class="token function">doubleCountPlusOne</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
130<span class="line">      <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>doubleCount <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">;</span></span>
131<span class="line">    <span class="token punctuation">}</span><span class="token punctuation">,</span></span>
132<span class="line">  <span class="token punctuation">}</span><span class="token punctuation">,</span></span>
133<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
134<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>組件內使用可直接透過 store 拿</p><div class="language-javascript line-numbers-mode" data-highlighter="prismjs" data-ext="js"><pre><code class="language-javascript"><span class="line"><span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span></span>
135<span class="line">  <span class="token function">setup</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
136<span class="line">    <span class="token keyword">const</span> store <span class="token operator">=</span> <span class="token function">useStore</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
137<span class="line"></span>
138<span class="line">    store<span class="token punctuation">.</span>counter <span class="token operator">=</span> <span class="token number">3</span></span>
139<span class="line">    store<span class="token punctuation">.</span>doubleCount <span class="token comment">// 6</span></span>
140<span class="line">  <span class="token punctuation">}</span></span>
141<span class="line"><span class="token punctuation">}</span></span>
142<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="options-api-support-1" tabindex="-1"><a class="header-anchor" href="#options-api-support-1"><span><strong>Options API Support</strong></span></a></h4><p>一樣使用 <code>mapState</code> 在 options 中註冊 getters</p><div class="language-javascript line-numbers-mode" data-highlighter="prismjs" data-ext="js"><pre><code class="language-javascript"><span class="line"><span class="token keyword">
142import</span> <span class="token punctuation">{</span> mapState <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&#39;pinia&#39;</span><span class="token punctuation">;</span></span>
143<span class="line"><span class="token keyword">import</span> <span class="token punctuation">{</span> useStore <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&#39;./store/main&#39;</span><span class="token punctuation">;</span></span>
144<span class="line"></span>
145<span class="line"><span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span></span>
146<span class="line">  <span class="token literal-property property">computed</span><span class="token operator">:</span> <span class="token punctuation">{</span></span>
147<span class="line">    <span class="token operator">...</span><span class="token function">mapState</span><span class="token punctuation">(</span>useStore<span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">&#39;doubleCount&#39;</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
148<span class="line">  <span class="token punctuation">}</span><span class="token punctuation">,</span></span>
149<span class="line"><span class="token punctuation">}</span></span>
150<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="actions" tabindex="-1"><a class="header-anchor" href="#actions"><span>Actions</span></a></h3><p>actions 就像組件中的 methods,且支援 async function,跟 state, getters 相同,透過 <code>this</code> 可以調用取得</p><div class="language-javascript line-numbers-mode" data-highlighter="prismjs" data-ext="js"><pre><code class="language-javascript"><span class="line"><span class="token keyword">export</span> <span class="token keyword">const</span> useStore <span class="token operator">=</span> <span class="token function">defineStore</span><span class="token punctuation">(</span><span class="token string">&#39;main&#39;</span><span class="token punctuation">,</span> <span class="token punctuation">{</span></span>
151<span class="line">  <span class="token function-variable function">state</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span><span class="token punctuation">{</span></span>
152<span class="line">    <span class="token literal-property property">counter</span><span class="token operator">:</span> <span class="token number">0</span><span class="token punctuation">,</span></span>
153<span class="line">  <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
154<span class="line">  <span class="token literal-property property">actions</span><span class="token operator">:</span> <span class="token punctuation">{</span></span>
155<span class="line">    <span class="token function">increment</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
156<span class="line">      <span class="token keyword">this</span><span class="token punctuation">.</span>counter<span class="token operator">++</span><span class="token punctuation">;</span></span>
157<span class="line">    <span class="token punctuation">}</span><span class="token punctuation">,</span></span>
158<span class="line">    <span class="token function">randomizeCounter</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
159<span class="line">
159      <span class="token keyword">this</span><span class="token punctuation">.</span>counter <span class="token operator">=</span> Math<span class="token punctuation">.</span><span class="token function">round</span><span class="token punctuation">(</span><span class="token number">100</span> <span class="token operator">*</span> Math<span class="token punctuation">.</span><span class="token function">random</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
160<span class="line">    <span class="token punctuation">}</span><span class="token punctuation">,</span></span>
161<span class="line">  <span class="token punctuation">}</span><span class="token punctuation">,</span></span>
162<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span></span>
163<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="調用" tabindex="-1"><a class="header-anchor" href="#調用"><span><strong>調用</strong></span></a></h4><div class="language-javascript line-numbers-mode" data-highlighter="prismjs" data-ext="js"><pre><code class="language-javascript"><span class="line"><span class="token keyword">import</span> <span class="token punctuation">{</span> useStore <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&#39;./store/main&#39;</span><span class="token punctuation">;</span></span>
164<span class="line"></span>
165<span class="line"><span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span></span>
166<span class="line">  <span class="token function">setup</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
167<span class="line">    <span class="token keyword">const</span> store <span class="token operator">=</span> <span class="token function">useStore</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
168<span class="line">    store<span class="token punctuation">.</span><span class="token function">increment</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
169<span class="line">  <span class="token punctuation">}</span><span class="token punctuation">,</span></span>
170<span class="line"><span class="token punctuation">}</span></span>
171<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="options-api-support-2" tabindex="-1"><a class="header-anchor" href="#options-api-support-2"><span><strong>Options API Support</strong></span></a></h4><p>與 Vuex 相同可透過 <code>mapActions</code> 註冊</p><div class="language-javascript line-numbers-mode" data-highlighter="prismjs" data-ext="js"><pre><code class="language-javascript"><span class="line"><span class="token keyword">import</span> <span class="token punctuation">{</span> mapActions <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&#39;pinia&#39;</span><span class="token punctuation">;</span></span>
172<span class="line"><span class="token keyword">
172import</span> <span class="token punctuation">{</span> useStore <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&#39;./store/main&#39;</span><span class="token punctuation">;</span></span>
173<span class="line"></span>
174<span class="line"><span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span></span>
175<span class="line">  <span class="token literal-property property">methods</span><span class="token operator">:</span> <span class="token punctuation">{</span></span>
176<span class="line">    <span class="token operator">...</span><span class="token function">mapActions</span><span class="token punctuation">(</span>useStore<span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">&#39;increment&#39;</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
177<span class="line">  <span class="token punctuation">}</span><span class="token punctuation">,</span></span>
178<span class="line"><span class="token punctuation">}</span></span>
179<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="subscribe-actions" tabindex="-1"><a class="header-anchor" href="#subscribe-actions"><span><strong>Subscribe actions</strong></span></a></h4><p>可使用 <code>$onAction</code> 監聽 action 的調用,詳細可參考<a href="https://pinia.esm.dev/core-concepts/actions.html#subscribing-to-actions" target="_blank" rel="noopener noreferrer">官方說明</a></p><div class="language-javascript line-numbers-mode" data-highlighter="prismjs" data-ext="js"><pre><code class="language-javascript"><span class="line"><span class="token comment">// 回傳 unsubscribe 函數</span></span>
180<span class="line"><span class="token keyword">const</span> unsubscribe <span class="token operator">=</span> store<span class="token punctuation">.</span><span class="token function">$onAction</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> name<span class="token punctuation">,</span> after<span class="token punctuation">,</span> onError <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span></span>
181<span class="line">  <span class="token keyword">if</span> <span class="token punctuation">(</span>name <span class="token operator">===</span> <span class="token string">&#39;increment&#39;</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
182<span class="line">    <span class="token keyword">const</span> startTime <span class="token operator">=</span> Date<span class="token punctuation">.</span><span class="token function">now</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
183<span class="line"></span>
184<span class="line">    <span class="token comment">// after 會在 action 調用完全返回後才執行</span></span>
185<span class="line">    <span class="token comment">// 會等待所有回傳的 promise</span></span>
186<span class="line">    <span class="token function">after</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">result</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span></span>
187<span class="line">      console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span></span>
188<span class="line">
188        <span class="token template-string"><span class="token template-punctuation string">\`</span><span class="token string">Finished &quot;</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">\${</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">&quot; after </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">\${</span></span>
189<span class="line">          Date<span class="token punctuation">.</span><span class="token function">now</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-</span> startTime</span>
190<span class="line">        <span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">ms.\\nResult: </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">\${</span>result<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">.</span><span class="token template-punctuation string">\`</span></span></span>
191<span class="line">      <span class="token punctuation">)</span><span class="token punctuation">;</span></span>
192<span class="line">    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
193<span class="line"></span>
194<span class="line">    <span class="token comment">// onError 會在 action 報錯時調用</span></span>
195<span class="line">    <span class="token function">onError</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">error</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span></span>
196<span class="line">      console<span class="token punctuation">.</span><span class="token function">warn</span><span class="token punctuation">(</span></span>
197<span class="line">        <span class="token template-string"><span class="token template-punctuation string">\`</span><span class="token string">Failed &quot;</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">\${</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">&quot; after </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">\${</span>Date<span class="token punctuation">.</span><span class="token function">now</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-</span> startTime<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">ms.\\nError: </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">\${</span>error<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">.</span><span class="token template-punctuation string">\`</span></span></span>
198<span class="line">      <span class="token punctuation">)</span></span>
199<span class="line">    <span class="token punctuation">}</span><span class="token punctuation">)</span></span>
200<span class="line">  <span class="token punctuation">}</span></span>
201<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span></span>
202<span class="line"></span>
203<span class="line"><span class="token comment">// 可手動移除監聽</span></span>
204<span class="line"><span class="token function">unsubscribe</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
205<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>
205如果在組件中調用 $onAction,則預設會在組件 unmounted 時移除監聽,如果要維持不被移除,則可以傳入第二個參數為 <code>true</code>,則該 subscribe 將不被自動移除</p><div class="language-javascript line-numbers-mode" data-highlighter="prismjs" data-ext="js"><pre><code class="language-javascript"><span class="line"><span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span></span>
206<span class="line">  <span class="token function">setup</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
207<span class="line">    <span class="token keyword">const</span> store <span class="token operator">=</span> <span class="token function">useStore</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
208<span class="line"></span>
209<span class="line">    <span class="token comment">// 這個 subscription 在 component unmounted 後仍會被保持</span></span>
210<span class="line">    store<span class="token punctuation">.</span><span class="token function">$onAction</span><span class="token punctuation">(</span>callback<span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span></span>
211<span class="line">  <span class="token punctuation">}</span><span class="token punctuation">,</span></span>
212<span class="line"><span class="token punctuation">}</span></span>
213<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="usage-組件外使用" tabindex="-1"><a class="header-anchor" href="#usage-組件外使用"><span>Usage 組件外使用</span></a></h2><p>組件外使用須特別注意調用時機,由於 pinia 的 store 完全依賴主核心 pinia 的安裝,需要確保所有 store hook 調用在 pinia 註冊在 app 後</p><div class="language-javascript line-numbers-mode" data-highlighter="prismjs" data-ext="js"><pre><code class="language-javascript"><span class="line"><span class="token keyword">import</span> pinia <span class="token keyword">from</span> <span class="token string">&#39;pinia&#39;</span><span class="token punctuation">;</span></span>
214<span class="line"><span class="token keyword">import</span> <span class="token punctuation">{</span> createApp <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&#39;vue&#39;</span><span class="token punctuation">;</span></span>
215<span class="line"><span class="token keyword">import</span> App <span class="token keyword">from</span> <span class="token string">&#39;./App.vue&#39;</span><span class="token punctuation">;</span></span>
216<span class="line"><span class="token keyword">import</span> <span class="token punctuation">{</span> useStore <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&#39;./store/main&#39;</span><span class="token punctuation">;</span></span>
217<span class="line"></span>
218<span class="line"><span class="token keyword">const</span> pinia <span class="token operator">=</span> <span class="token function">createPinia</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
219<span class="line"><span class="token keyword">const</span> app <span class="token operator">=</span> <span class="token function">createApp</span><span class="token punctuation">(</span>App<span class="token punctuation">)</span><span class="token punctuation">;</span></span>
220<span class="line"></span>
221<span class="line"><span class="token comment">// 先註冊</span></span>
222<span class="line">app<span class="token punctuation">.</span><span class="token function">
222use</span><span class="token punctuation">(</span>pinia<span class="token punctuation">)</span><span class="token punctuation">;</span></span>
223<span class="line"></span>
224<span class="line"><span class="token comment">// 後調用</span></span>
225<span class="line"><span class="token keyword">const</span> store <span class="token operator">=</span> <span class="token function">useStore</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
226<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>但刻意處理這種調用時機是非常累人的,建議都一律在函數 function 中調用即可保證 pinia 正確安裝完成</p><div class="language-javascript line-numbers-mode" data-highlighter="prismjs" data-ext="js"><pre><code class="language-javascript"><span class="line"><span class="token keyword">import</span> <span class="token punctuation">{</span> createRouter <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&#39;vue-router&#39;</span></span>
227<span class="line"></span>
228<span class="line"><span class="token keyword">const</span> router <span class="token operator">=</span> <span class="token function">createRouter</span><span class="token punctuation">(</span><span class="token punctuation">{</span></span>
229<span class="line">  <span class="token comment">// ...</span></span>
230<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
231<span class="line"></span>
232<span class="line"><span class="token comment">// X: 在函數外調用</span></span>
233<span class="line"><span class="token keyword">const</span> store <span class="token operator">=</span> <span class="token function">useStore</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
234<span class="line"></span>
235<span class="line">router<span class="token punctuation">.</span><span class="token function">beforeEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">to<span class="token punctuation">,</span> from<span class="token punctuation">,</span> next</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span></span>
236<span class="line">  <span class="token comment">// O: 在函數中調用</span></span>
237<span class="line">  <span class="token keyword">const</span> store <span class="token operator">=</span> <span class="token function">useStore</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
238<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span></span>
239<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="circular-dependency" tabindex="-1"><a class="header-anchor" href="#circular-dependency"><span>Circular Dependency</span></a></h3><p>大部分場景下這是會爆掉的,但 pinia 讓兩個組件之間可以彼此調用,只是需要特別注意可能的 side effect,不要同時呼叫彼此具有依賴關係的 action, getter 就沒問題</p><p><strong>store/main.js</strong></p><div class="language-javascript line-numbers-mode" data-highlighter="prismjs" data-ext="js"><pre><code class="language-javascript"><span class="line"><span class="token keyword">
239import</span> <span class="token punctuation">{</span> defineStore <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&#39;pinia&#39;</span><span class="token punctuation">;</span></span>
240<span class="line"><span class="token keyword">import</span> <span class="token punctuation">{</span> useCount <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&#39;./count&#39;</span><span class="token punctuation">;</span></span>
241<span class="line"></span>
242<span class="line"><span class="token comment">// X: 這裡呼叫 hook 會噴掉,因為 pinia 尚未註冊在 app 中</span></span>
243<span class="line"><span class="token keyword">const</span> Count <span class="token operator">=</span> <span class="token function">useCount</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
244<span class="line"></span>
245<span class="line"><span class="token keyword">export</span> <span class="token keyword">const</span> useMain <span class="token operator">=</span> <span class="token function">defineStore</span><span class="token punctuation">(</span><span class="token string">&#39;main&#39;</span><span class="token punctuation">,</span> <span class="token punctuation">{</span></span>
246<span class="line">  <span class="token function-variable function">state</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span><span class="token punctuation">{</span></span>
247<span class="line">    <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">&#39;Main&#39;</span><span class="token punctuation">,</span></span>
248<span class="line">  <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
249<span class="line">  <span class="token literal-property property">actions</span><span class="token operator">:</span> <span class="token punctuation">{</span></span>
250<span class="line">    <span class="token function">showName</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
251<span class="line">      <span class="token comment">// O: 在 action 中調用</span></span>
252<span class="line">      <span class="token keyword">const</span> Count <span class="token operator">=</span> <span class="token function">useCount</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
253<span class="line">      Count<span class="token punctuation">.</span>name<span class="token punctuation">;</span> <span class="token comment">// Count</span></span>
254<span class="line">    <span class="token punctuation">}</span><span class="token punctuation">,</span></span>
255<span class="line">  <span class="token punctuation">}</span><span class="token punctuation">,</span></span>
256<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
257<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p><strong>store/count.js</strong></p><div class="language-javascript line-numbers-mode" data-highlighter="prismjs" data-ext="js"><pre><code class="language-javascript"><span class="line"><span class="token keyword">
257import</span> <span class="token punctuation">{</span> defineStore <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&#39;pinia&#39;</span><span class="token punctuation">;</span></span>
258<span class="line"><span class="token keyword">import</span> <span class="token punctuation">{</span> useMain <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&#39;./main&#39;</span><span class="token punctuation">;</span></span>
259<span class="line"></span>
260<span class="line"><span class="token keyword">export</span> <span class="token keyword">const</span> useMain <span class="token operator">=</span> <span class="token function">defineStore</span><span class="token punctuation">(</span><span class="token string">&#39;count&#39;</span><span class="token punctuation">,</span> <span class="token punctuation">{</span></span>
261<span class="line">  <span class="token function-variable function">state</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span><span class="token punctuation">{</span></span>
262<span class="line">    <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">&#39;Count&#39;</span></span>
263<span class="line">  <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
264<span class="line">  <span class="token literal-property property">actions</span><span class="token operator">:</span> <span class="token punctuation">{</span></span>
265<span class="line">    <span class="token function">showName</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
266<span class="line">      <span class="token keyword">const</span> Main <span class="token operator">=</span> <span class="token function">useMain</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
267<span class="line">      Main<span class="token punctuation">.</span>name<span class="token punctuation">;</span> <span class="token comment">// Main</span></span>
268<span class="line">    <span class="token punctuation">}</span><span class="token punctuation">,</span></span>
269<span class="line">  <span class="token punctuation">}</span><span class="token punctuation">,</span></span>
270<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
271<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="composing-store" tabindex="-1"><a class="header-anchor" href="#composing-store"><span>Composing Store</span></a></h2><p>Pinia 建立模組的方式,除了傳統的 Vuex Options 模式外,還提供了原生 Vue3 的 Composition 模式</p><p>使用方式很簡單,把原本 Options 的參數改由 function 傳入,並在最後回傳所有東西即可,就像在組件中ä
271½¿ç”¨ setup 函數一樣,這種寫法提供了更為彈性的編寫風格,可以最大化狀態管理的靈活度,缺點也是顯而易見的,不當使用時是有可能會造成維護上寫法的混亂</p><div class="language-javascript line-numbers-mode" data-highlighter="prismjs" data-ext="js"><pre><code class="language-javascript"><span class="line"><span class="token keyword">const</span> useStore <span class="token operator">=</span> <span class="token function">defineStore</span><span class="token punctuation">(</span><span class="token string">&#39;main&#39;</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span></span>
272<span class="line">  <span class="token keyword">const</span> counter <span class="token operator">=</span> <span class="token function">ref</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
273<span class="line"></span>
274<span class="line">  <span class="token keyword">function</span> <span class="token function">increment</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
275<span class="line">    counter<span class="token punctuation">.</span>value <span class="token operator">+=</span> <span class="token number">1</span><span class="token punctuation">;</span></span>
276<span class="line">  <span class="token punctuation">}</span></span>
277<span class="line"></span>
278<span class="line">  <span class="token keyword">return</span> <span class="token punctuation">{</span></span>
279<span class="line">    counter<span class="token punctuation">,</span></span>
280<span class="line">    increment<span class="token punctuation">,</span></span>
281<span class="line">  <span class="token punctuation">}</span></span>
282<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span></span>
283<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><blockquote><p>這種寫法需要特別注意當模組彼此調用時的情況</p></blockquote><div class="language-javascript line-numbers-mode" data-highlighter="prismjs" data-ext="js"><pre><code class="language-javascript"><span class="line"><span class="token keyword">const</span> useA <span class="token operator">=</span> <span class="token function">defineStore</span><span class="token punctuation">(</span><span class="token string">&#39;a&#39;</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span></span>
284<span class="line">  <span class="token keyword">const</span> b <span class="token operator">=</span> <span class="token function">useB</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
285<span class="line"></span>
286<span class="line">  <span class="token comment">// X: 此處會報錯,因為 b 裡也同時讀取了 a.name</span></span>
287<span class="line">  b<span class="token punctuation">.</span>name<span class="token punctuation">;</span></span>
288<span class="line"></span>
289<span class="line">  <span class="token keyword">function</span> <span class="token function">showName</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
290<span class="line">    <span class="token comment">// O: 在 actions 或 getters 中讀取是沒問題的</span></span>
291<span class="line">    <span class="token keyword">const</span> bName <span class="token operator">=</span> b<span class="token punctuation">.</span>name<span class="token punctuation">;</span></span>
292<span class="line">  <span class="token punctuation">}</span></span>
293<span class="line"></span>
294<span class="line">  <span class="token keyword">return</span> <span class="token punctuation">{</span></span>
295<span class="line">    <span class="token literal-property property">
295name</span><span class="token operator">:</span> <span class="token function">ref</span><span class="token punctuation">(</span><span class="token string">&#39;I am A&#39;</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
296<span class="line">  <span class="token punctuation">}</span></span>
297<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
298<span class="line"></span>
299<span class="line"><span class="token keyword">const</span> useB <span class="token operator">=</span> <span class="token function">defineStore</span><span class="token punctuation">(</span><span class="token string">&#39;b&#39;</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span></span>
300<span class="line">  <span class="token keyword">const</span> a <span class="token operator">=</span> <span class="token function">useA</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
301<span class="line"></span>
302<span class="line">  <span class="token comment">// X: 此處會報錯,因為 a 裡也同時讀取了 b.name</span></span>
303<span class="line">  a<span class="token punctuation">.</span>name<span class="token punctuation">;</span></span>
304<span class="line"></span>
305<span class="line">  <span class="token keyword">return</span> <span class="token punctuation">{</span></span>
306<span class="line">    <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token function">ref</span><span class="token punctuation">(</span><span class="token string">&#39;I am B&#39;</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
307<span class="line">  <span class="token punctuation">}</span></span>
308<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
309<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>以上就是本次開箱 Pinia 的主要功能,進入 v2.0.0 後內部引用 vue-demi 正式同時支援 Vue2, Vue3,雖然知名度尚不如目前 Vuex,但相信不久後 Pinia 將會正式被推薦取代 Vuex</p><p>下次見拉~=V=</p>`,80)),p(a,{hashtags:"vuejs3, pinia"})])}const k=e(l,[["render",u]]),v=JSON.parse('{"path":"/articles/js/pinia-intro.html","title":"Pinia - Vuex 的後繼者","lang":"zh-TW","frontmatter":{},"git":{"updatedTime":1748788505000,"contributors":[{"name":"johnnywang1994","username":"johnnywang1994","email":"[email protected]","commits":5,"url":"https://github.com/johnnywang1994"},{"name":"Lindy Liao","username":"","email":"[email protected]","commits":1}],"changelog":[{"hash":"f01bfa128b4d33fbeddb8abb1697b5391b273d28","time":1748788505000,"email":"[email protected]","author":"Lindy Liao","message":"UPD"},{"hash":"71ccb7693345c8ddc2f554e00f8a0ce73af2b783","time":1648521821000,"email":"[email protected]","author":"johnnywang1994","message":"UPD: upgrade to v2"},{"hash":"69c4efa0ab4c842f52cc47c6a4423269c161e3af","time":1642582868000,"email":"[email protected]","author":"johnnywang1994","message":"UPD: update pinia vue2 hint"},{"hash":"da1521dcf805739a83e5efa4e52581013a51dcad","time":1638541816000,"email":"[email protected]","author":"johnnywang1994","message":"UPD: update sociallinks"},{"hash":"5462f39c3447f0f8414e62396aeb3bb3de51884d","time":1638540999000,"email":"[email protected]","author":"johnnywang1994","message":"UPD: add share-social"},{"hash":"c4ca9580ccb32721836c623a0d54209378966997","time":1637824964000,"email":"[email protected]","author":"johnnywang1994","message":"UPD: add pinia-intro"}]},"filePathRelative":"articles/js/pinia-intro.md"}');export{k as comp,v as data};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.