繁体   English   中英

如何使用 Typescript 在 Vue 3 中正确循环引用组件?

[英]How to correctly circular reference components in Vue 3 with Typescript?

我有两个 Vue 组件。 为了简单起见,我将它们称为组件 A组件 B

组分 A

<template>
    <div>{{ recursive.text }} component A</div>
    <component-b v-if="recursive.value" :recursive="recursive.value" />
</template>

<script lang="ts">
    import { defineAsyncComponent, defineComponent } from 'vue';
    export default defineComponent({
        name: 'ComponentA',
        components: {
            ComponentB: defineAsyncComponent(() => import('./B.vue')),
        },
    });
</script>

<script lang="ts" setup>
    interface RecursiveProp {
        text: string;
        value?: RecursiveProp;
    }

    const props = defineProps<{ recursive: RecursiveProp }>();
</script>

B组份

<template>
    <div>{{ recursive.text }} component B</div>
    <component-a v-if="recursive.value" :recursive="recursive.value" />
</template>

<script lang="ts">
    import { defineAsyncComponent, defineComponent } from 'vue';

    export default defineComponent({
        name: 'ComponentB',
        components: {
            ComponentA: defineAsyncComponent(() => import('./A.vue')),
        },
    });
</script>

<script lang="ts" setup>
    interface RecursiveProp {
        text: string;
        value?: RecursiveProp;
    }

    const props = defineProps<{ recursive: RecursiveProp }>();
</script>

例如,当我将组件 A导入另一个组件并传递正确的 props 时,代码可以正常工作,并且不会在浏览器中显示任何错误。 组件 A组件 B根据给定的 prop 递归渲染指定的次数。 但是由于某种原因,当组件以这种方式相互引用时,Visual Studio Code 会抱怨。 我在下面附上了错误的图片。 此错误存在于组件 A组件 B中。

在此处输入图像描述

在 Vue 文档中,在处理边缘案例部分中引用了这个问题。 唯一的问题是它是 Vue 2 文档: https ://v2.vuejs.org/v2/guide/components-edge-cases.html#Circular-References-Between-Components

在 Vue 3 中,您可以使用defineAsyncComponent 这使我的代码工作,但使错误出现在 Visual Studio 代码中:https ://vuejs.org/guide/components/async.html#async-components=

我知道我可以全局注册其中一个组件。 但这是我想避免的。

有没有办法使用 Typescript 在 Vue 3 中正确循环引用组件?

这个问题似乎只影响<script lang="ts">并且与 IDE 或<script setup lang="ts">无关。

一种解决方法是在<script setup lang="ts">而不是<script lang="ts">中注册递归异步组件:

<!-- A.vue -->
<template>
    <div>{{ recursive.text }} component A</div>
    <component-b v-if="recursive.value" :recursive="recursive.value" />
</template>

<script lang="ts" setup>
import { defineAsyncComponent } from 'vue'
           👇
const ComponentB = defineAsyncComponent(() => import('./B.vue')) 

interface RecursiveProp {
    text: string;
    value?: RecursiveProp;
}

const props = defineProps<{ recursive: RecursiveProp }>();
</script>
<!-- B.vue -->
<template>
    <div>{{ rec.text }} component B</div>
    <component-a v-if="rec.value" :recursive="rec.value" />
</template>

<script lang="ts" setup>
import { defineAsyncComponent, computed } from 'vue'
         👇
const ComponentA = defineAsyncComponent(() => import('./A.vue'))

interface RecursiveProp {
    text: string;
    value?: RecursiveProp;
}

const props = defineProps<{ recursive: RecursiveProp }>();

// compute stop-condition for the recursion
const rec = computed(() => ({
    ...props.recursive,
    value: undefined
} as RecursiveProp))
</script>

演示

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM