首頁  >  問答  >  主體

使用 Vue3 和 TypeScript 將 Pinia Store 作為 Prop 傳遞

<p>我正在使用 Typescript、Pinia 和 Vue3,並且有一個 <code>MenuButton</code> 元件,我希望能夠傳遞用於選單開啟狀態以及要顯示的操作的 Pinia 儲存/隱藏。應用程式中有幾個不同的選單,因此我希望能夠將它們傳入,並且它們都使用相同的工廠來定義商店。我正在嘗試弄清楚如何讓所有這些都與打字稿一起使用。 </p> <pre class="lang-js prettyprint-override"><code>// nav.store.ts import { defineStore } from "pinia"; import { useStorage } from "@vueuse/core"; import type { RemovableRef } from "@vueuse/core"; export interface MenuStore { isOpen: RemovableRef<boolean>, toggle(force?: boolean) : void, open(): void, close(): void, } interface State { isOpen: RemovableRef<boolean>; } function menuStoreFactory(id: string) { return defineStore(id, { state: () : State => ({ isOpen: useStorage(`${id}-open`, false), }), actions: { toggle(force?: boolean) { this.isOpen = force != undefined ? force : !this.isOpen; }, open() { this.isOpen = true; }, close() { this.isOpen = false; } } }); } export const useMainMenuStore = menuStoreFactory('mainMenu'); export const useMobileMenuStore = menuStoreFactory('mobileMenu'); </code></pre> <pre class="lang-js prettyprint-override"><code>// setup script for the menu button component import { MenuIcon, MenuLeftIcon } from "@/icons"; import type { MenuStore } from "@/modules/nav/nav.store"; interface Props { controller: MenuStore } const props = defineProps<Props>(); </code></pre> <p>那麼用法就很簡單了:</p> <pre class="lang-html prettyprint-override"><code><template> <MenuButton :controller="mainMenu" ></MenuButton> </template> <script setup lang=ts"> const mainMenu = useMainMenuStore(); </script> </code></pre> <p>在目前介面中,我收到了道具不匹配的錯誤。經過一番研究,我將介面變成了以下內容,修復了使用錯誤,但隨後在<code>MenuButton</code> 組件中引發了<code>toggle()</code> 和< code>isOpen< 的錯誤/code> 尚未解決。</p>
匯出介面 MenuStore 擴充 PiniaCustomStateProperties<{
    isOpen: RemovableRef,
    切換(力?:布林值):無效,
    開啟():無效,
    關閉():無效,
}> {}
</代號></pre>
<p>另一個接近的嘗試調整是:</p>
<pre class="lang-js Prettyprint-override"><code>匯出介面 MenuStore 擴充 Store<string, {
    isOpen: RemovableRef,
    切換(力?:布林值):無效,
    開啟():無效,
    關閉():無效,
}> {}
</代號></pre>
<p>這導致使用時出現此錯誤,但中元件沒有錯誤</p>
型別 _StoreWithState & UnwrapRef<狀態> & _StoreWithGetters<{}> & {toggle(force?: boolean): void, close(): void, open(): void} & PiniaCustomProperties & PiniaCustomStateProperties<狀態>無法分配給類型 MenuStore ...   類型 PiniaCustomStateProperties;不可分配給類型 MenuStore

P粉899950720P粉899950720399 天前595

全部回覆(1)我來回復

  • P粉187677012

    P粉1876770122023-08-26 14:00:15

    您的問題似乎主要是關於您需要的類型/接口,所以我會回答這個問題。

    您可以簡單地使用傳回的儲存的類型,而不是自己編寫類型。

    您有一個工廠函數,它會傳回 defineStore 的回傳值,它本身就是一個傳回儲存的函數。因此,可以使用 typeof 取得工廠函數的類型,然後使用 TypeScript 的 ReturnType 幫助器深入了解傳回類型,從而找到儲存的類型。

    以下應該是您所需要的:

    export type MenuStore = ReturnType<ReturnType<typeof menuStoreFactory>>
    

    細分:

    ReturnType<                 // C
      ReturnType<               // B
        typeof menuStoreFactory // A
      >
    >
    
    • A:取得工廠函數的型別。
    • B:取得工廠函數的回傳類型,即defineStore的回傳值。這本身就是一個返回儲存的函數。
    • C: 取得該函數的傳回型別。這是商店本身的類型。

    回覆
    0
  • 取消回覆