Слот Vue загружает асинхронный компонент до того, как в слот вступает оператор v-if - PullRequest
0 голосов
/ 08 июня 2018

У меня проблема с тем, что компоненты синхронизации загружаются перед тем, как он будет показан.

Компоненты, импортированные с 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 голосов
/ 08 июня 2018

С документ о области компиляции

Все в родительском шаблоне скомпилировано в родительской области;все в дочернем шаблоне компилируется в дочерней области.

Вот почему возникает ваша проблема.В родительском шаблоне нет ничего, что указывало бы на то, что компонент не должен отображаться.

Это можно решить, используя Слоты с областью действия

simpleпример: 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>
...