1

我遇到了一个问题,即在实际显示之前加载了同步组件 JavaScript。

使用 a 导入的组件dynamic-import显示v-if为在需要时加载它们。当它们被显示时,它们的 JavaScript 也会被加载。但是对于 a 的情况,slotv-if 不会阻止组件已经加载其生成的 JavaScript 块并将其附加到 DOM。

下拉组件:

<template>
    <li class="dropdown" :class="{ open: visible }">
        <div class="heading" @click.stop="toggle">
            <span>{{ heading }}</span>
        </div>

        <div class="slot-content" v-if="visible">
            <slot></slot>
        </div>
    </li>
</template>

google-map在插槽中使用带有异步组件的组件:

<dropdown>
    <google-map>
        <map-marker :data="{{ $marker }}"></map-marker>
    </google-map>
</dropdown>

即使插槽有v-if,组件 JavaScript 仍在加载中。奇怪的是,mounted 或 created 都没有被触发。因此,除了组件的异步加载之外,似乎一切都遵守适当的规则。

最好我可以将插槽与 a 一起使用,v-if而不是触发为该async组件加载生成的块。

显然,如果它异步加载不是什么大问题,但即使是 HTTP2 在涉及请求时也有其局限性。我宁愿在需要时加载它。

4

1 回答 1

5

来自关于编译范围的文档

父模板中的所有内容都在父范围内编译;子模板中的所有内容都在子范围内编译。

That's why your problem occurs. There's nothing in the parent template that indicates that the component shouldn't be rendered.

It can be solved by using Scoped Slots

simple example: https://jsfiddle.net/jacobgoh101/8kmLpj75/6/

In the example, just by adding <template slot-scope="{}"> to the async component, it forces the async component to wait until the slot's parent scope becomes available. (I honestly don't know its exact inner working either).

In your case, simply adding <template slot-scope="{}"> should solve the problem as well

<dropdown>
    <template slot-scope="{}">
        <google-map>
            <map-marker :data="{{ $marker }}"></map-marker>
        </google-map>
    </template>
</dropdown>
于 2018-06-08T13:32:51.207 回答