使用 Vue3 和 TypeScript 将 Pinia Store 作为 Prop 传递
P粉899950720
P粉899950720 2023-08-25 18:40:12
[Vue.js讨论组]

我正在使用 Typescript、Pinia 和 Vue3,并且有一个 MenuButton 组件,我希望能够传递用于菜单打开状态以及要显示的操作的 Pinia 存储/隐藏。应用程序中有几个不同的菜单,因此我希望能够将它们传入,并且它们都使用相同的工厂来定义商店。我正在尝试弄清楚如何让所有这些都与打字稿一起使用。

// 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');
// 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>();

那么用法就非常简单了:

<template>
    <MenuButton
        :controller="mainMenu"
    ></MenuButton>
</template>
<script setup lang=ts">
    const mainMenu = useMainMenuStore();
</script>

在当前界面中,我收到了道具不匹配的错误。经过一番研究,我将界面变成了以下内容,修复了使用错误,但随后在 MenuButton 组件中引发了 toggle()isOpen< 的错误/code> 尚未解决。

export interface MenuStore extends PiniaCustomStateProperties<{
    isOpen: RemovableRef<boolean>,
    toggle(force?: boolean) : void,
    open(): void,
    close(): void,
}> {}

另一个接近的尝试调整是:

export interface MenuStore extends Store<string, {
    isOpen: RemovableRef<boolean>,
    toggle(force?: boolean) : void,
    open(): void,
    close(): void,
}> {}

这导致了使用时出现此错误,但组件中没有错误

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

P粉899950720
P粉899950720

全部回复(1)
P粉187677012

您的问题似乎主要是关于您需要的类型/接口,所以我会回答这个问题。

您可以简单地使用返回的存储的类型,而不是自己编写类型。

您有一个工厂函数,它返回 defineStore 的返回值,它本身就是一个返回存储的函数。因此,可以使用 typeof 获取工厂函数的类型,然后使用 TypeScript 的 ReturnType 帮助器深入了解返回类型,从而找到存储的类型。

以下应该是您所需要的:

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

细分:

ReturnType<                 // C
  ReturnType<               // B
    typeof menuStoreFactory // A
  >
>
  • A:获取工厂函数的类型。
  • B:获取工厂函数的返回类型,即defineStore的返回值。这本身就是一个返回存储的函数。
  • C: 获取该函数的返回类型。这是商店本身的类型。
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号