Vue slot 在 slot v-if 语句启动之前加载异步组件

Ste*_*n-v 1 javascript webpack vue.js vue-component vuejs2

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

使用a 导入的组件dynamic-import显示v-if为在需要时加载它们。当它们显示时,它们的 JavaScript 也会被加载。但在 v-if 的情况下,slot不会阻止组件加载其生成的 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>
Run Code Online (Sandbox Code Playgroud)

组件与google-map插槽中的异步组件的用法:

<dropdown>
    <google-map>
        <map-marker :data="{{ $marker }}"></map-marker>
    </google-map>
</dropdown>
Run Code Online (Sandbox Code Playgroud)

即使槽有一个v-if,组件 JavaScript 仍在加载。奇怪的是,安装的或创建的都没有被解雇。所以看起来除了组件的异步加载之外,一切都遵守正确的规则。

最好我可以使用带有 a 的插槽,v-if并且不触发加载该async组件生成的块。

显然,如果它是异步加载的话,这并不是一个大问题,但即使是 HTTP2 在请求方面也有其局限性。我宁愿在需要时加载它。

Jac*_*Goh 5

来自有关编译范围的文档

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

这就是你的问题出现的原因。父模板中没有任何内容表明不应呈现该组件。

可以通过使用Scoped Slots来解决

简单的例子:https ://jsfiddle.net/jacobgoh101/8kmLpj75/6/

在示例中,只需添加<template slot-scope="{}">到异步组件,它就会强制异步组件等待,直到插槽的父作用域变得可用。(老实说,我也不知道其确切的内部工作原理)。

在您的情况下,只需添加<template slot-scope="{}">也应该可以解决问题

<dropdown>
    <template slot-scope="{}">
        <google-map>
            <map-marker :data="{{ $marker }}"></map-marker>
        </google-map>
    </template>
</dropdown>
Run Code Online (Sandbox Code Playgroud)