In React I was able to update a Boolean value from the child component using a useState
in a prop to pass a new value back and forward, however in Vue I’m struggling to do similar.
I have been able to pass the Boolean value to the child component by doing this:
Parent:
<template>
<button @click="viewProduct()"
<ChildComponent v-if="showProduct === true" :showProduct = showProduct />
</template>
<script setup>
import { ref, defineProps } from 'vue'
import ChildComponent from './ChildComponent.vue'
let showProduct = ref(false)
const viewProduct = (e) => {
showProduct.value = true
}
</script>
and I can see the value passed through to the child as a prop and I can use it in the child component.
However if I try to change the variable in the child component with something like this:
Child:
<template>
<div class="close" @click="hidePDP()">X</div>
</template>
<script setup>
import { defineProps, computed } from 'vue'
const props = defineProps({
showProduct: Boolean,
});
const hidePDP = computed( () => {
return props.showProduct = false
});
</script>
I get these errors and I’m guessing props even when they’ve been a ref()
value still don’t like you mutating them.
60:16 error Unexpected mutation of "showProduct" prop vue/no-mutating-props
60:16 error Unexpected side effect in computed function
However I haven’t been able to successfully find a way to update the Boolean value in the child (reverse the Boolean value) so the parent can remove the ChildComponent
element from the render when a close button is clicked in the Child Component itself.
I hope that makes sense, I’ve seen a few questions that talk about getting help for the reverse of sending prop data to the child from the parent (which I’ve already got working) like props value not sending the updated value from parent to child component in vue and Creating local copy of passed props in child component in vue.js?, but not an exact answer to the above.
2
Answers
I see 2 major mistakes in the code you provide.
First, you’re trying to mutate the prop, and the second you’re doing anything but counting in computed.
Best practise in vue is to send prop to a ChildComponent and listen emits from it and mutate in the parent component.
Parent component:
Child:
useful links:
https://vuejs.org/guide/components/events.html#component-events
https://vuejs.org/guide/essentials/computed.html#getters-should-be-side-effect-free
If your component should be bind both ways look at v-model for components:
https://vuejs.org/guide/components/v-model.html#component-v-model
Just use v-model:
Playground
Child:
I would even prefer to move
v-if
into the child:Playground
Or even move the show button into the child… so no any
v-model
is needed.