• Fri, Mar 2026

Reusable Components and Best Practices in Vue.js

Reusable Components and Best Practices in Vue.js

This comprehensive tutorial dives into creating reusable components in Vue.js. You’ll learn how to design flexible, maintainable components, leverage props and slots effectively, and follow best practices for scalable Vue projects. Step-by-step examples and actionable instructions make it perfect for beginners and experienced developers alike.

Introduction: Why Reusable Components Matter

When I first started working with Vue.js, I was amazed at how quickly I could build UI elements. But soon, I realized that many components were duplicated across pages. That’s when the concept of reusable components became my best friend.

Reusable components help:

  • Reduce code duplication
  • Maintain consistent UI across the app
  • Enable easier testing and debugging
  • Improve scalability and maintainability

In this tutorial, we’ll explore how to build reusable Vue components effectively and follow best practices that make your projects robust.

Step 1: Setting Up Your Vue.js Project

If you don’t have a project yet, start with Vite for a fast development environment:

npm init vue@latest reusable-components-demo
cd reusable-components-demo
npm install
npm run dev

Now your environment is ready for component creation.

Step 2: Creating a Simple Reusable Component

Let’s start by creating a simple Button.vue component that can be reused with different labels and styles.

Button.vue

<template>
 <button : @click="$emit('click')">
  <slot>Default Button</slot>
 </button>
</template>

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

const props = defineProps({
 type: {
  type: String,
  default: "primary"
 }
});

const btnClass = computed(() => {
 return {
  'btn-primary': props.type === 'primary',
  'btn-secondary': props.type === 'secondary'
 }
});
</script>

<style scoped>
.btn-primary { background-color: #3490dc; color: #fff; padding: 8px 16px; border: none; border-radius: 4px; cursor: pointer; }
.btn-secondary { background-color: #6c757d; color: #fff; padding: 8px 16px; border: none; border-radius: 4px; cursor: pointer; }
</style>

Explanation:

  • Uses props to customize button type.
  • Emits click event for parent interaction.
  • Uses a default slot for flexibility.

Step 3: Using the Reusable Button Component

Let’s use our reusable Button.vue component in App.vue.

App.vue

<template>
  <div>
    <h1>Reusable Button Example</h1>
    <Button type="primary" @click="handleClick">Primary Button</Button>
    <Button type="secondary" @click="handleClick">Secondary Button</Button>
  </div>
</template>

<script setup>
import Button from './components/Button.vue';

const handleClick = () => {
  alert("Button clicked!");
};
</script>

Result: Both buttons are using the same component but render differently based on the type prop and slot content.

Step 4: Leveraging Props for Flexibility

Props allow parent components to pass data to reusable components, making them versatile.

Example: Card Component with Props

<template>
 <div >
  <h3>{{ title }}</h3>
  <p>{{ content }}</p>
 </div>
</template>

<script setup>
const props = defineProps({
 title: { type: String, required: true },
 content: { type: String, required: true }
});
</script>

<style scoped>
.card { border: 1px solid #ccc; padding: 16px; border-radius: 8px; margin-bottom: 12px; }
</style>

Now we can create multiple cards dynamically with different titles and content.

Step 5: Using Slots for Content Injection

Slots allow parent components to inject content into child components, making them even more reusable.

Example: Modal Component with Slots

<template>
 <div >
  <header><slot name="header">Default Header</slot></header>
  <main><slot>Default Content</slot></main>
  <footer><slot name="footer">Default Footer</slot></footer>
 </div>
</template>

<script setup></script>

<style scoped>
.modal { background: #fff; padding: 16px; border-radius: 8px; border: 1px solid #ddd; }
</style>

Usage: Inject custom content for header, body, and footer using named slots.

Step 6: Best Practices for Reusable Components

  • Keep components focused: Each component should handle a single responsibility.
  • Use props and slots: Make components flexible and avoid hardcoded content.
  • Name components clearly: Use descriptive names like UserCard or PrimaryButton.
  • Encapsulate styles: Use scoped styles to avoid conflicts.
  • Emit events thoughtfully: Keep parent-child communication clear and predictable.
  • Document component API: Props, events, and slots should be clearly described for team use.
  • Write unit tests: Ensure components behave consistently across usage scenarios.

Step 7: Creating a Library of Components

Once you have reusable components, you can organize them into a component library:

  • Create a components/ folder with subfolders like buttons/, cards/, modals/.
  • Export all components from an index.js file for easy imports.
  • Use consistent naming and file structure to make it scalable for larger projects.

Step 8: Real-World Example – Dashboard UI

Combine reusable buttons, cards, and modals to build a dashboard:

<template>
 <div >
  <Button type="primary" @click="showModal = true">Add User</Button>

  <Card v-for="user in users" :key="user.id" :title="user.name" :content="user.email" />

  <Modal v-if="showModal" @close="showModal = false">
   <template #header><h3>New User</h3></template>
   <form>...form fields...</form>
   <template #footer><Button @click="showModal=false">Cancel</Button></template>
  </Modal>
 </div>
</template>

<script setup>
import { ref } from 'vue';
import Button from './components/Button.vue';
import Card from './components/Card.vue';
import Modal from './components/Modal.vue';

const showModal = ref(false);
const users = ref([
 { id: 1, name: 'Alice', email: 'alice@example.com' },
 { id: 2, name: 'Bob', email: 'bob@example.com' }
]);
</script>

Result: A fully data-driven dashboard built using reusable components and following best practices.

Conclusion

Reusable components are the backbone of scalable Vue.js applications. By leveraging props, slots, and clear component patterns, you can create flexible, maintainable, and scalable UI elements. Following best practices ensures that your components remain easy to use, test, and extend as your project grows. Start small, build a component library, and watch your Vue applications become cleaner, faster, and more efficient.

This website uses cookies to enhance your browsing experience. By continuing to use this site, you consent to the use of cookies. Please review our Privacy Policy for more information on how we handle your data. Cookie Policy