Passez Pinia Store en tant qu'accessoire en utilisant Vue3 et TypeScript
P粉899950720
2023-08-25 18:40:12
<p>J'utilise Typescript, Pinia et Vue3 et j'ai un composant <code>MenuButton</code> et je souhaite pouvoir transmettre le stockage/masquer Pinia pour l'état d'ouverture du menu et l'action à afficher. . Il existe plusieurs menus différents dans l'application, je souhaite donc pouvoir les transmettre et les faire utiliser tous la même usine pour définir le magasin. J'essaie de comprendre comment faire fonctionner tout cela avec du texte dactylographié. </p>
<pre class="lang-js Prettyprint-override"><code>// nav.store.ts
importer {defineStore } depuis "pinia" ;
importer { useStorage } depuis "@vueuse/core";
importer le type { RemoveRef } depuis "@vueuse/core";
interface d'exportation MenuStore {
isOpen : AmovibleRef<boolean>,
toggle(force?: booléen) : vide,
open() : vide,
close() : vide,
}
État de l'interface {
isOpen : AmovibleRef<boolean>;
}
fonction menuStoreFactory(id : chaîne) {
return definitionStore(id, {
état : () : État =>
isOpen : useStorage(`${id}-open`, false),
}),
Actions: {
basculer(forcer ? : booléen) {
this.isOpen = force != non défini force : !this.isOpen;
},
ouvrir() {
this.isOpen = vrai ;
},
fermer() {
this.isOpen = faux ;
}
}
});
}
export const useMainMenuStore = menuStoreFactory('mainMenu');
export const useMobileMenuStore = menuStoreFactory('mobileMenu');
</code></pre>
<pre class="lang-js Prettyprint-override"><code>// script de configuration pour le composant du bouton de menu
importer { MenuIcon, MenuLeftIcon } depuis "@/icons" ;
importer le type { MenuStore } depuis "@/modules/nav/nav.store" ;
Accessoires d'interface {
contrôleur : MenuStore
}
const props = définirProps<Props>();
</code></pre>
<p>L'utilisation est alors très simple :</p>
<pre class="lang-html Prettyprint-override"><code><template>
<BoutonMenu
:controller="mainMenu"
></MenuButton>
</modèle>
<configuration du script lang=ts">
const mainMenu = useMainMenuStore();
</script>
</code></pre>
<p>Dans l'interface actuelle, je reçois une erreur de non-concordance d'accessoires. Après quelques recherches, j'ai modifié l'interface comme suit, ce qui a corrigé l'erreur d'utilisation, mais j'ai ensuite lancé <code>toggle()</code> dans le composant <code>MenuButton</code> /code> pour code>isOpen<</p>
<pre class="lang-js Prettyprint-override"><code>interface d'exportation MenuStore étend PiniaCustomStateProperties<{
isOpen : AmovibleRef<boolean>,
toggle(force?: booléen) : vide,
open() : vide,
close() : vide,
}> {}
</code></pre>
<p>另一个接近的尝试调整是:</p>
<pre class="lang-js Prettyprint-override"><code>interface d'exportation MenuStore étend Store<string, {
isOpen : AmovibleRef<boolean>,
toggle(force?: booléen) : vide,
open() : vide,
close() : vide,
}> {}
</code></pre>
<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<État> n'est pas attribuable au type MenuStore... Tapez PiniaCustomStateProperties<State> n'est pas attribuable au type MenuStore</pre></p>
Votre question semble porter principalement sur les types/interfaces dont vous avez besoin, je vais donc y répondre.
Vous pouvez simplement utiliser le type stocké renvoyé au lieu d'écrire le type vous-même.
Vous disposez d'une fonction d'usine qui renvoie
defineStore
的返回值,它本身就是一个返回存储的函数。因此,可以使用typeof
获取工厂函数的类型,然后使用 TypeScript 的ReturnType
L'assistant explore le type de retour pour trouver le type stocké.Ce qui suit devrait être ce dont vous avez besoin :
Segmentation :
defineStore
. C'est en soi une fonction qui renvoie le stockage.