Buttons

Dynamic buttons in Nuxt 3 allows reusable and customizable button components that can adapt to different styles, sizes, and behaviors based on props. This ensures flexibility while maintaining a consistent UI.

Why Use Dynamic Buttons?

Reusability: A single button component can be used across multiple pages with different styles and functionalities.

Consistency: Ensures a uniform look and feel across the application.

Scalability: Easy to extend with new features such as loading states, icons, or additional styles.

Maintainability: Reduces duplicate code and simplifies updates.

Using a dynamic button component is one of the best approaches for managing buttons in a Nuxt 3 application. It allows for flexibility while maintaining DRY (Don't Repeat Yourself) principles. However, if an application has very specific button requirements, using separate components for different button types might be a better alternative. Ultimately, this approach is optimal for most projects needing scalable UI components.

Creating a Dynamic Button Component

Create a new component BaseButton.vue inside the components folder.

<template>
  <button
    :class="computedClasses"
    :disabled="disabled"
    @click="handleClick"
  >
    <slot name="icon-left"></slot>
    <span><slot></slot></span>
    <slot name="icon-right"></slot>
  </button>
</template>

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

const props = defineProps({
  type: {
    type: String,
    default: 'button',
  },
  color: {
    type: String,
    default: 'primary',
  },
  size: {
    type: String,
    default: 'md',
  },
  disabled: {
    type: Boolean,
    default: false,
  },
});

const emit = defineEmits(['click']);

const computedClasses = computed(() => {
  return [
    'rounded-lg px-4 py-2 font-semibold transition-all duration-200',
    props.disabled ? 'opacity-50 cursor-not-allowed' : '',
    props.color === 'primary' ? 'bg-blue-500 text-white hover:bg-blue-600' : '',
    props.color === 'secondary' ? 'bg-gray-500 text-white hover:bg-gray-600' : '',
    props.size === 'sm' ? 'text-sm py-1 px-2' : '',
    props.size === 'lg' ? 'text-lg py-3 px-6' : '',
  ];
});

const handleClick = () => {
  if (!props.disabled) {
    emit('click');
  }
};
</script>

<style scoped>
button {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}
</style>

You can use the BaseButton component in different parts of your Nuxt 3 application.

Example Usage
<script setup>
import BaseButton from '~/components/BaseButton.vue';

const handleButtonClick = () => {
  console.log('Button clicked!');
};
</script>

<template>
  <div>
    <BaseButton color="primary" size="md" @click="handleButtonClick">
      Click Me
    </BaseButton>

    <BaseButton color="secondary" size="lg" disabled>
      Disabled Button
    </BaseButton>
  </div>
</template>