Flaquito183
Flaquito183

Reputation: 49

Access modal that is in another component in vuejs

I'm starting to work with vuejs. I have downloaded a template to start the development of a system; everything was right until I wanted to use a modal. It is in a component called baseLayout.vue and I tried to use it in a method in another component. Is it possible that I can manipulate it from another component? I want to open it, update the body with other elements. A fragment of my code is given below:

baseLayout.vue

<template>
<b-modal id="modal1" ref="modal1" title="Bootstrap-Vue">
    <p class="my-4">Hello from modal!</p>
</b-modal></template>

I tried to use it from here Analytics.vue

<template>
<button class="btn-pill btn-shadow btn-wide fsize-1 btn btn-danger btn-lg" v-on:click="showModal()">ShowModal</button></template>

In the scripts:

methods: {
  showModal(){
    this.$refs.modal1.show()
  }
}

I can not find a way to manipulate the modal that is in the component. And I have to use it from there because if I put it in the current component, it is superimposed by the header and other elements.

Upvotes: 2

Views: 5391

Answers (2)

ilyas Jumadurdyew
ilyas Jumadurdyew

Reputation: 930

I've found easier way of calling modal from outside of the component

Let's assume that we have some modal component

myModal.vue

<template>
    <div>
        <b-modal title="BootstrapVue" v-model="show_modal">
            <p class="my-4">Hello from modal!</p>
        </b-modal>
    </div>
</template>


<script>
export default {
    name: "myModal",
    data() {
        return {
            show_modal: false
        }
    }
}
</script>

Key to success here is to bind v-model to the key from data()

Then in main component lets call it myView.vue

myView.vue

<template>
    <div>
        <!-- button that call modal -->
        <b-button @click="$refs['main-modal'].show_modal = true">
            Launch demo modal
        </b-button>
        <!-- component in which we have modal -->
        <myModal ref="main-modal"/>
    </div>
</template>


<script>
import myModal from "@/modals/myModal.vue";

export default {
    name: "myView",
    components: {
        myModal
    }
}
</script>

Upvotes: 0

Oleksandr Danylchenko
Oleksandr Danylchenko

Reputation: 699

I faced pretty the same problem.

  1. You can pass modalShow field as a prop to the BaseLayout.vue component and modify modal as
    <b-modal v-model="modalShow">...</b-modal> (BootstarpPropExample).
    But I found this way pretty complicated if modal window in a separate component. That's because you have to pass, emit and process modalShow variable state across all levels.

IMHO the second way is more laconic and fancier

  1. In BaseLayout.vue add show() method:

    <template>
        <b-modal id="modal1" ref="modal1" title="Bootstrap-Vue">
            <p class="my-4">Hello from modal!</p>
        </b-modal>
    </template>
    
    <script>
        export default {
            methods: {
                show() {
                    this.$refs.modal1.show();
                }
            }
        }
    </script>
    

    And in Analytics.vue import modal component and insert it into the template with a preferable ref name, so you can also call his methods with $refs:

    <template>
        <div>
            <button class="btn-pill btn-shadow btn-wide btn btn-danger btn-lg" @click="showModal()">
                ShowModal
            </button>
            <BaseLayout ref="modalComponent"/>
        </div>
    </template>
    
    <script>
        import BaseLayout from "./BaseLayout";
    
        export default {
            components: {
                BaseLayout
            },
            methods: {
                showModal() {
                    this.$refs.modalComponent.show();
                }
            }
        }
    </script>
    

Upvotes: 3

Related Questions