Can I dynamically create / destroy Vue components?

2019-07-27 21:59发布

So, I'm creating a fairly complex Vue application that fetches data from our backend API and displays it on the front-end, depending on filters the person selects. Its default is to display everything at once, then once the user selects filters, it will pull out the "card" components that don't have those attributes. Everything has been going great until today, which I tried to add Google Maps into it, via their API (I'm using the vue2-google-maps package to make this easier on myself, since we plan to implement Polylines in the future).

The problem is that I'm utilizing Foundation as my CSS framework and initializing the map within a Reveal modal. The only way I've been able to get the modal working without any warnings in the console is by using an example I found online which utilizes the mounted() property:

mounted() {
  $(this.$el).foundation();
},
unmounted() {
  $(this.$el).foundation.destroy();
}

This works great, until I try to call a Google Map inside the modal, because instead of creating the map when the modal fires, it creates everything on page load. Not a big deal if I was only creating a few maps... but on-load I'm rendering 92 maps. As you can imagine, this is incredibly slow.

In its simplest form, the structure of my app is:

<app>
    <filters-component></filters-component>
    <div class="off-canvas-content">
        <nav-component></nav-component>
        <div class="row card-grid">
            <card-component>
                <modal-component></modal-component>
            </card-component>
        </div>
    </div>
</app>

Currently, the modal component is the only nested component, mostly just so it's easier to keep track of what modal belongs to which card.

Before, I was using a method to fire each modal, which looked like this, with a @click event on the open modal button, however, this still renders all maps on load and also gives a console error that reads "VM215130:180 Tried to initialize reveal on an element that already has a Foundation plugin." If you click the button more than once.

<a :data-toggle="'modal-' + school.id" @click="openModal(school.id)" class="float-right" tabindex="0" aria-label="Open More window" title="Open More window">
    More <icon name="info-circle" label="More information icon"></icon>
</a>

<script>
    export default {
        methods: {
            openModal: function($schoolid) {
                $('#modal-' + $schoolid).foundation();
                console.log('modal-' + $schoolid + ' launched')
            }
        }
</script>

Is there a way to only create the modal component when this button is clicked, or somehow lazy load it only when the modal is opened?

0条回答
登录 后发表回答