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

时间:2018-06-08 07:56:02

标签: javascript webpack vue.js vuejs2 vue-component

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

使用dynamic-import显示使用v-if导入的组件,以便在需要时加载它们。当他们被显示时,他们的JavaScript也被加载。但是在slot的情况下,v-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仍在加载中。奇怪的是,安装或创建都没有被解雇。所以除了组件的异步加载外,似乎一切都遵循正确的规则。

最好我可以使用带有v-if的插槽,而不会触发为此async组件加载生成的块。

显然,如果它异步加载它不是一个大问题,但即使HTTP2在请求时也有其限制。我宁愿在需要时加载它。

1 个答案:

答案 0 :(得分:4)

来自the doc about Compilation Scope

  

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

这就是您的问题发生的原因。父模板中没有任何内容表明该组件不应该被渲染。

可以使用 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>