How to open modal component with @click

I created two components: navbar and modal.

In navbar I would like to do the following to open the modal:
<a class=“no-formatting with-border login-link” href=“javascript:” @click.prevent=“loginModal = true”>

and my modal has this setting:

<div v-if="loginModal" class="app-modal login hidden-modal shown">
.....

I need navbar @click to set the “loginModal” value of the modal component to “true”.

How do I do it?

Hi

In the nabar component you don’t set a value but emit an event to the the parent component with $emit(‘showModal’) or something. The parent component listens for this event and changes the loginModal variable and the v-if is on the modal-component and not inside it.

Does it make sense?

can you provide full code so that i can check

Check my answer here: VueJs Form & child Components

1 Like

My Navbar component is:

<template>
<div class="navbar">
    <nav class="middle-section ">
       <a href="javascript:" @click.prevent="loginModal = true">Login</a>
    </nav>
</div>

</template>

<script>
    export default {
      
    }
</script>

My Modal component is:

<template>

<div v-if="loginModal" class="app-modal login hidden-modal shown">
    ...........
</div>
</template>

<script>
    export default {
    	data: function() {
            return {
                loginModal: false
            }
        }
    }
</script>

I’m using laravel and the blade template looks like this:

<navbar-guest></navbar-guest>
<modal-login></modal-login>

I’m having a hard time understanding $ emit, I tried to use it in some ways and couldn’t make it work. I simply need to @click the Navbar component to set true to “modalLogin” value of the Modal component

Can anyone give me an example?

Hi

I think you have to try wrapping your head around $emit again. It is a really important concept. It is how child components communicate with their parents. You should write it something like this:

Navbar

<template>
<div class="navbar">
    <nav class="middle-section ">
       <a href="#" @click.prevent="$emit('login')">Login</a>
    </nav>
</div>

Parent

<navbar-gues @login="modalLogin = true"></navbar-guest>
<modal-login v-if="modalLogin = true"></modal-login>

And modalLogin is a data of the parent. If the modal closes it can emit an event to the parent which catches this and sets modalLogin to false (not written here).

1 Like

Check my reply bro???

1 Like

I appreciate your help, but I still can’t make it work. Even using the examples the most I could do returns this error:

Property or method "loginModal" is not defined on the instance but referenced during rendering. Make sure this property is reactive, either in the data option, or for class-based components, by initializing the property.

My component Navbar:
<a href="javascript:" @click.prevent="$emit('login')">

My component modal:

    export default {
    	data: function() {
            return {
                loginModal: false
            }
        }
    }
</script>

In blade template:

<navbar-guest @login="loginModal = true" ></navbar-guest>
<modal-login v-if="loginModal"></modal-login>

It’s not right ? Why does an error occur that the loginModal is not set, and it is returned as Data () in the Modal component?

The data value for loginModal should not be inside the modal component but in the parent. It is used in the parents template.

did that and also keeps returning the same error

I discovered the error. I was placing the “return data” locally in the “navbar.vue” file. When I put in the “const app = new Vue” in the “app.js” file it works. But doesn’t this take up unnecessary memory and processing?

Once the user is logged in I see no need to have these information compiled into the vue file.

How do I make this work with a local rather than a global setting?

I don’t really understand what you mean by local vs global. Can you post your code?

Global is when it is inside the Vuejs instance (app.js) and local when it is inside the .vue file (navbar.vue). At least that’s how I learned

Hi

If you have some data in one component or the other shouldn’t mak any difference in processing and memory requirements.