简体   繁体   English

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

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

I have two Vue components.我有两个 Vue 组件。 For simplicity of this question I called them component A and component B .为了简单起见,我将它们称为组件 A组件 B

Component A组分 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>

Component B 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>

For example, when I import Component A into another component and pass it the correct props, the code works with no errors showing in the browser.例如,当我将组件 A导入另一个组件并传递正确的 props 时,代码可以正常工作,并且不会在浏览器中显示任何错误。 Component A and Component B recursively render the specified amount of times based on the given prop.组件 A组件 B根据给定的 prop 递归渲染指定的次数。 But for some reason Visual Studio Code complains when the components reference to each other in this way.但是由于某种原因,当组件以这种方式相互引用时,Visual Studio Code 会抱怨。 I attached a picture of the error below.我在下面附上了错误的图片。 This error is present in both component A and component B .此错误存在于组件 A组件 B中。

在此处输入图像描述

In the Vue documentation, this problem is referenced inside the Handling Edge Cases section.在 Vue 文档中,在处理边缘案例部分中引用了这个问题。 The only problem is that it is Vue 2 documentation: https://v2.vuejs.org/v2/guide/components-edge-cases.html#Circular-References-Between-Components唯一的问题是它是 Vue 2 文档: https ://v2.vuejs.org/v2/guide/components-edge-cases.html#Circular-References-Between-Components

In Vue 3 you can use defineAsyncComponent .在 Vue 3 中,您可以使用defineAsyncComponent This makes my code work, but makes the error appear in Visual Studio code:https://vuejs.org/guide/components/async.html#async-components=这使我的代码工作,但使错误出现在 Visual Studio 代码中:https ://vuejs.org/guide/components/async.html#async-components=

I am aware I can globally register one of the components.我知道我可以全局注册其中一个组件。 But that is something I want to avoid.但这是我想避免的。

Is there a way to correctly circular reference components in Vue 3 with Typescript?有没有办法使用 Typescript 在 Vue 3 中正确循环引用组件?

It seems this issue only affects <script lang="ts"> and is unrelated to the IDE or the <script setup lang="ts"> .这个问题似乎只影响<script lang="ts">并且与 IDE 或<script setup lang="ts">无关。

A workaround is to register the recursive async components in <script setup lang="ts"> instead of <script 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>

demo 演示

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

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