Vue 插槽在插槽 v-if 语句启动之前加载异步组件
Posted
技术标签:
【中文标题】Vue 插槽在插槽 v-if 语句启动之前加载异步组件【英文标题】:Vue slot loads async component before the slot v-if statement kicks in 【发布时间】:2018-11-18 05:44:35 【问题描述】:我遇到了一个问题,即在实际显示之前加载了同步组件 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 组件仍在加载中。奇怪的是,mounted 或 created 都没有被触发。因此,除了组件的异步加载之外,似乎一切都遵守适当的规则。
最好我可以将插槽与v-if
一起使用,而不是触发为该async
组件加载生成的块。
如果异步加载显然不是什么大问题,但即使是 HTTP2 在涉及请求时也有其限制。我宁愿在需要时加载它。
【问题讨论】:
尝试使用v-cloak
,它将用CSS隐藏html,直到组件完全加载。
v-cloak
只是应用一个dislay: none
,它不会阻止异步生成的 JavaScript 仍然被加载。另外,我已经尝试过使用它,但无济于事。
【参考方案1】:
来自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>
【讨论】:
谢谢,这似乎有效,但我希望对它的工作原理进行更多解释。但它现在完成了这项工作。谢谢! 我也很惊讶这行得通,也很想解释一下哈哈以上是关于Vue 插槽在插槽 v-if 语句启动之前加载异步组件的主要内容,如果未能解决你的问题,请参考以下文章
Vue-七七创建全局组件——“Loading“ 使用extend创建组件——弹出层 单继承:vue组件间的继承。——继承js的部分 异步组件加载 异步组件工厂 组件插槽