In modern web development, efficient component design and seamless data communication are crucial for building interactive and maintainable user interfaces. Vue 3, with its Composition API and <script setup>
syntax, introduces powerful tools to streamline component creation and data handling. One key feature of Vue 3 is attribute inheritance, which simplifies the management of dynamic attributes in components.
In this article, we will explore how to create child components in Vue 3, pass data between parent and child components, and leverage attribute inheritance for a more flexible and cleaner component design. We will cover practical examples and best practices to help you harness the full potential of Vue 3's capabilities, making your development process more intuitive and efficient.
Creating a Simple TextArea Component
Create a new Vue component file named TextArea.vue with the following content:
<template>
<textarea
:value="modelValue"
@input="handleInput"
></textarea>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue';
const props = defineProps({
modelValue: String
});
const emit = defineEmits(['update:modelValue']);
const handleInput = (event) => {
emit('update:modelValue', event.target.value);
};
</script>
Here’s an example of how you can use the TextArea component in a parent component:
<template>
<div>
<TextArea v-model="commentBody" />
<p>Your comment: {{ commentBody }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue';
import TextArea from './TextArea.vue'; // Adjust the path as needed
// Define a ref to hold the textarea value
const commentBody = ref('');
</script>
Now watch carefully. We don't need to emit update value element from child component. Vue 3 does this for us.
Parent Component Listens for the update:modelValue Event: The parent component listens for the update:modelValue event because of the v-model directive:
<TextArea v-model="commentBody" />
Vue internally converts this v-model into the following:
<TextArea :modelValue="commentBody" @update:modelValue="val => commentBody = val" />
This means that whenever the update:modelValue event is emitted from the child component, the parent updates its commentBody variable with the new value (the value the user typed).
This two-way binding mechanism is how the data flows between the parent and the child component in Vue.
Understanding Attribute Inheritance
In Vue 3, any extra attributes (like class, id, or style) passed to a component that are not explicitly defined in props are automatically added to the root element of the template by default. This feature is known as attribute inheritance or attribute forwarding. This is a really cool and useful feature.
<TextArea v-model="commentBody" class="textclass" id="textid"/>
When you pass attributes like class or id, they automatically to the root element of a component.
In this example they (class and id) will apply to the <textarea>
(root of child component) element.