I am working on a Vue 3 app. I have 3 nested components: a button component, which is nested inside a navigation component, which is nested inside a content component.
The button should toggle the value of the boolean variable isVisible
inside the grandparent component Main.vue
(content component).
In the grandchild component MyButton.vue
:
<template>
<button @click="handleClick" >
{{ label }}
</button>
</template>
<script>
export default {
name: 'MyButton',
props: {
label: String,
isVisible: Boolean
},
emits: [
'toggleVisibility',
],
methods: {
handleClick() {
this.$emit('toggleVisibility')
}
}
}
</script>
In the parent component Navigation.vue
:
<template>
<div >
<MyButton
:label='"Toggle content"'
:isVisible=false
@toggleVisibility="$emit('toggleVisibility')"
/>
</div>
</template>
<script>
import MyButton from './MyButton'
export default {
emits: [
'toggleVisibility',
],
}
</script>
In the grandparent component Main.vue
:
<template>
<div >
<Navigation />
<div v-if="isVisible" >
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
</div>
</div>
</template>
<script>
import Navigation from './Ui/Navigation'
export default {
name: 'Main',
components: {
Navigation
},
props: {
title: String,
tagline: String,
},
data() {
return {
isVisible: false,
}
},
methods: {
toggleVisibility() {
console.log('ok');
this.isVisible = !this.isVisible;
}
}
}
</script>
The problem
As can be seen above, I tried to emit upwards, one component at a time.
For a reason I was unable to understand, this does not work.
Questions
- Where is my mistake?
- What is the shortest viable solution?
CodePudding user response:
#1 You didn't declare MyButton
component in you parent Navigation
component.
Add this inside export default {}
components: {
MyButton
},
#2 You aren't listening to the event in you grand parent Main
component.
Replace the <Navigation />
line with:
<Navigation @toggleVisibility="toggleVisibility" />
P.S: Prefer kebab-case
for custom defined events. Just a best practice. toggle-visiblity
instead of toggleVisibility