DEV Community

Cover image for The pieces of UI: Components 🧩
Domenico Tenace
Domenico Tenace

Posted on • Updated on • Originally published at javascript.plainenglish.io

The pieces of UI: Components 🧩

Overview

Components allow us to divide the user interface into independent, reusable parts, each independent of the other and they are considered the basis of an interface built with Vue.
In this article we will see what Components are and how they are used in a Vue app.
Let's start! 🤙


What is a Component?

A Component is a reusable and independent portion of code that defines a specific element of the interface.
A Vue Component, internally, encapsulates structure, style and logic (HTML,CSS,JavaScript).
Components are one of Vue's strong points, thanks to their flexibility and the possibility of using them in different points of the software.

Defining and using a Component

We typically define each Vue component in a dedicated file using the .vue extension for create it, in this way:

<script setup>
import { ref } from 'vue'

const count = ref(0)
</script>

<template>
  <button @click="count++">You clicked me {{ count }} times.</button>
</template>
Enter fullscreen mode Exit fullscreen mode

The example above defines a simple button component that when clicked, will increment a counter.
To use a child component, we need to import it in the parent component:

<script setup>
import ButtonCounter from './ButtonCounter.vue'
</script>

<template>
  <h1>Hello button!</h1>
  <ButtonCounter />
</template>
Enter fullscreen mode Exit fullscreen mode

Now, will render a button in the page.
We can also use more than one on the page in this way:

<template>
  <h1>Hello buttons!</h1>
  <ButtonCounter />
  <ButtonCounter />
  <ButtonCounter />
</template>
Enter fullscreen mode Exit fullscreen mode

Now, each button is an instance in itself, so when you click one of them, its counter will be incremented.

It's also possible to globally register a component, making it available to all components in a given app without having to import it


What are Props?

Props are custom attributes you can register on a component.
Let's take the following Component as an example:

<script setup>
defineProps(['label'])
</script>

<template>
  <button>{{ label }}</button>
</template>
Enter fullscreen mode Exit fullscreen mode

defineProps is a compile-time macro that is only available inside <script setup> and does not need to be explicitly imported. Declared props are automatically exposed to the template. defineProps also returns an object that contains all the props passed to the component, so that we can access them in JavaScript if needed:

const props = defineProps(['label'])
console.log(props.label)
Enter fullscreen mode Exit fullscreen mode

Once a prop is registered, you can pass data to it as a custom attribute, like this:

<template>
  <h1>Hello buttons!</h1>
  <ButtonCounter label="Increment"/>
  <ButtonCounter label="Decrement"/>
</template>
Enter fullscreen mode Exit fullscreen mode

Let's define a more practical example:

<script setup>
import { ref } from "vue";

const posts = ref([
  { id: 1, title: 'Data binding: Directives 🫰' },
  { id: 2, title: 'Reactivity: ref() vs reactive() 👊' },
  { id: 3, title: 'Conditional rendering: v-if vs v-show 🫴'}
])
</script>

<template>
  <BlogPost
   v-for="post in posts"
   :key="post.id"
   :title="post.title"
  />
</template>
Enter fullscreen mode Exit fullscreen mode

Suppose that BlogPost is a Component defined in another file and takes title as a prop.
In the above example we see an array of posts in a v-for and the v-bind is applied on the title property.
v-bind is used to pass dynamic prop values. This is especially useful when you don't know the exact content you're going to render ahead of time.


Slots

Let's take the ButtonCounter component as an example: has a prop called label that defines the text inside it.
The same Component can be rewritten using slot and obtaining the same result:

<template>
  <button><slot /></button>
</template>
Enter fullscreen mode Exit fullscreen mode

And when called:

<script setup>
import ButtonCounter from './ButtonCounter.vue'
</script>

<template>
  <h1>Hello button!</h1>
  <ButtonCounter>Increment</ButtonCounter>
</template>
Enter fullscreen mode Exit fullscreen mode

Conclusion

Components are fundamental for build app Vue. Their encapsulation of functionality, reusability, and ease of integration make them a powerful tool for building scalable and maintainable web applications.
Happy coding!✨


Hi👋🏻
My name is Domenico, software developer passionate of Vue.js framework, I write article about it for share my knowledge and experience.
Don't forget to visit my Linktree to discover my projects 🫰🏻

Linktree: https://linktr.ee/domenicotenace

Follow me on dev.to for other articles 👇🏻

If you like my content or want to support my work on GitHub, you can support me with a very small donation.
I would be grateful 🥹

Top comments (0)