'How do I change a Boolean variable's value from a grandchild component in this Vue 3 application?
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" class="btn btn-sm btn-success">
{{ 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 class="navigation">
<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 class="main">
<Navigation />
<div v-if="isVisible" class="content">
<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?
Solution 1:[1]
#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
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Pavan Aditya M S |
