Pass Pinia Store as Prop using Vue3 and TypeScript
P粉899950720
P粉899950720 2023-08-25 18:40:12
0
1
474
<p>I'm using Typescript, Pinia and Vue3, and have a <code>MenuButton</code> component and I want to be able to pass the Pinia storage/hide for the menu open state and the action to show. There are a few different menus in the application so I want to be able to pass them in and have them all use the same factory to define the store. I'm trying to figure out how to get all of this to work with typescript. </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>Then usage is very simple:</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>In the current interface, I receive a prop mismatch error. After some research, I changed the interface to the following, which fixed the usage error, but then threw <code>toggle()</code> and < in the <code>MenuButton</code> component The error /code> for code>isOpen< has not been resolved.</p> <pre class="lang-js prettyprint-override"><code>export interface MenuStore extends PiniaCustomStateProperties<{ isOpen: RemovableRef<boolean>, toggle(force?: boolean) : void, open(): void, close(): void, }> {} </code></pre> <p>另一个接近的尝试调整是:</p> <pre class="lang-js prettyprint-override"><code>export interface MenuStore extends Store<string, { isOpen: RemovableRef<boolean>, toggle(force?: boolean) : void, open(): void, close(): void, }> {} </code></pre> <p>这导致了使用时出现此错误,但组件中没有错误</p> <pre class="brush:php;toolbar:false;">Type _StoreWithState<string, State, {}, {toggle(force?: boolean): void, close(): void, open(): void}> & UnwrapRef<State> & _StoreWithGetters<{}> & {toggle(force?: boolean): void, close(): void, open(): void} & PiniaCustomProperties<string, State, {}, {toggle(force?: boolean): void, close(): void, open(): void}> & PiniaCustomStateProperties<State> is not assignable to type MenuStore ...   Type PiniaCustomStateProperties<State> is not assignable to type MenuStore</pre></p>
P粉899950720
P粉899950720

reply all(1)
P粉187677012

Your question seems to be mostly about the types/interfaces you need, so I'll answer that.

You can simply use the returned stored type instead of writing the type yourself.

You have a factory function that returns the return value of defineStore, which is itself a function that returns a store. Therefore, you can use typeof to get the type of the factory function, and then use TypeScript's ReturnType helper to drill down into the return type to find the stored type.

The following should be what you need:

export type MenuStore = ReturnType>

Segmentation:

ReturnType<                 // C
  ReturnType<               // B
    typeof menuStoreFactory // A
  >
>
  • A: Get the type of factory function.
  • B: Get the return type of the factory function, that is, the return value of defineStore. This itself is a function that returns storage.
  • C: Get the return type of this function. This is the type of store itself.
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!