I have a Vue.js component in which I am using the syntax. I have a "name" props that I get from the parent component. I want to set up a two-way communication between parent and child components using this props.
Here's what the code of the parent component looks like:
<script setup>
import Greeting from './components/Greeting.vue'
import CreateTodo from './components/CreateTodo.vue'
import TodosList from './components/TodosList.vue'
import { ref, computed, watch, onMounted } from 'vue'
const name = ref('')
watch(name, newVal => {
localStorage.setItem('name', newVal)
})
onMounted(() => {
name.value = localStorage.getItem('name') || ''
})
</script>
<template>
<main class="main">
<Greeting class="greeting-section"/>
</main>
</template>
And what my child component "Greeting.vue" looks like:
<script setup>
import MyInputName from './UI/MyInputName.vue'
defineProps({
name: {
type: String,
required: true,
},
})
</script>
<template>
<section>
<div class="container">
<h2 class="title">
What's up,
<MyInputName placeholder="Name here" type="text"/>
</h2>
</div>
</section>
</template>
It seems to me that it should be implemented using emit, but I do not quite understand how to implement it because instead of standard input I use custom UI component MyInput:
<template>
<input
:type="type"
:name="name"
:placeholder="placeholder"
:value="modelValue"
@input="$emit('update:modelValue', $event.target.value)"
/>
</template>
<script setup>
defineProps({
modelValue: {
modelValue: [String, Number],
},
name: {
type: String,
},
type: {
type: String,
required: true,
},
placeholder: {
type: String,
}
})
defineEmits(['update:modelValue'])
</script>
<style scoped>
input[type="text"] {
display: block;
width: 100%;
font-size: 1.125rem;
padding: 1rem 1.5rem;
color: var(--white);
background-color: #FFF;
border-radius: 0.5rem;
box-shadow: var(--shadow);
margin-bottom: 1.5rem;
color: var(--dark);
}
input[type="radio"],
input[type="checkbox"] {
display: none;
}
input[type="submit"] {
display: block;
width: 100%;
font-size: 1.125rem;
padding: 1rem 1.5rem;
color: #FFF;
background-color: var(--primary);
border-radius: 0.5rem;
box-shadow: var(--personal-glow);
cursor: pointer;
transition: 0.2s ease-in-out;
}
</style>
In
Greeting.vue
component define an emit then use writable computed property that get the prop and when it's set it emits the value to parent :In parent :