Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Craytor's avatar

Dynamic Modal Content With Vue.js

I'm trying to integrate dynamic modals within my application. For example, I have a table of data, and I have a button that is "edit content". In a perfect world a modal would pop up and there would be the data from the selected row in the modal in a fashion that would make logical sense. The title would be the modal title, the description would be editable, and there would be a submit button.

Is there such a way that you could only have one modal (so you don't have to have x amount of modals when you have x rows in the table), and the change out the content when you change the content? Also is there a way to send data back to the parent component? Should the modal be a component? If so, how would I go about doing this?

Any help would be greatly appreciated!

0 likes
5 replies
davielee's avatar
davielee
Best Answer
Level 11

Hey @Craytor I recently did something like this. I would suggest you do something like this (of course using your needed markup, this is just to illustrate the point).

ModalContainer.vue

<template>
    <div class="modal" v-if="active" @click.self="close">
        <header>
            <h2>{{title}}</h2>
        </header>
        <section>
            <component :is="component" :data="data"></component>
        </section>
    </div>
</template>

<script>
import Hub from '../events/Hub';
import ExampleModalBody from './ExampleModalBody.vue';

export default {
    data() {
        active: false,
        data: {},
        title: null,
    },

    components: {
        ExampleModalBody
    },

    destroyed() {
        Hub.$off('set-modal-data', this.set);
        Hub.$off('open-modal', this.open);
    },

    methods: {
        close() {
            this.active = false;
        },

        open() {
            this.active = true;
        },

        set(data, title) {
            this.data = data;
            this.title = title;
            this.component = title.split(' ').join('-').toLowerCase(); // of course you could just pass the component through the method too...
        }
    },

    mounted() {
        this.$nextTick(function () {
            Hub.$on('set-modal-data', this.set);
            Hub.$on('open-modal', this.open);
        }.bind(this));
    }
}
</script>

This would be your base modal. The Hub file is just a Vue instance like the following to use as an event hub.

Hub.js

const Vue = require('vue');
const Hub = new Vue();

export default Hub;

In your blade views (or whatever you're using), you can add a <modal-container></modal-container> tag and then have a method fire off the open-modal and set-modal-data events like shown above.

SomeButtonComponent.vue

<script>
import Hub from '../events/Hub';

export default {
    data() {
        return {
            data: {}
        }
    },

    methods: {
        open() {
            Hub.$emit('open-modal');
            Hub.$emit('set-modal-data', this.data, 'Component Title');
        }
    }
}
</script>
6 likes
Craytor's avatar

@craigpaul That is great! That is exactly what I was needing to do, many thanks! Question though, is it possible to send data from the modal back to the "parent" component? Thanks again!

davielee's avatar

@Craytor you're welcome. Yes it's the same process using $emit(), $on() and $off(). Wherever you want to fire the event you use emit, then you add the listener with on wherever you want to respond to it.

1 like
nosnevetzy's avatar

@craigpaul canyou explain it further? I'm new with vue.js and I also want to have dynamic content when it comes to my modal. What would be the result on the blade template? What should I put on the ExampleModalBody? A pure html? Please help. Thanks.

Please or to participate in this conversation.