Hone logo
Hone
Problems

Vue Global Component Registration

This challenge focuses on mastering the creation and registration of global components in a Vue.js application using TypeScript. Global components are incredibly useful for creating reusable UI elements like buttons, modals, or layout structures that can be used anywhere in your application without explicit imports in every parent component.

Problem Description

Your task is to create a Vue 3 application in TypeScript that utilizes global components. You will need to:

  1. Create a reusable Button component: This component should accept a label prop for its text content and a type prop to define its appearance (e.g., 'primary', 'secondary', 'danger').
  2. Register the Button component globally: Make it available for use in any Vue component without needing to import it directly.
  3. Create a simple App component: This component will demonstrate the usage of the globally registered Button component in various scenarios.

Key Requirements:

  • The Button component should be written in TypeScript and use the Composition API or Options API as appropriate.
  • The Button component must accept a label (string) and type (string, with default to 'primary') prop.
  • The type prop should influence the styling of the button (e.g., by adding a CSS class). You can use basic CSS for this.
  • The Button component should emit a click event when clicked.
  • The registration of the Button component must be done globally within your Vue application's entry point (e.g., main.ts).
  • The App.vue component should render multiple instances of the Button component with different labels and types, and handle the click event to log a message to the console.

Expected Behavior:

  • When the application runs, you should see three buttons displayed: a primary button with the label "Click Me", a secondary button with the label "Learn More", and a danger button with the label "Delete Item".
  • Clicking any of these buttons should log a message to the browser's developer console, indicating which button was clicked (e.g., "Primary button clicked!", "Secondary button clicked!", "Danger button clicked!").

Edge Cases to Consider:

  • What happens if the type prop is not provided? (It should default to 'primary').
  • Ensure the click event is correctly emitted and handled.

Examples

Example 1: Basic Button Usage

// In App.vue
<template>
  <div>
    <Button label="Submit" />
  </div>
</template>

// Expected rendered HTML (simplified)
<div>
  <button class="btn btn-primary">Submit</button>
</div>

Example 2: Button with Different Types and Event Handling

// In App.vue
<template>
  <div>
    <Button label="Save Changes" type="secondary" @click="handleSaveClick" />
  </div>
</template>

<script setup lang="ts">
const handleSaveClick = () => {
  console.log('Save Changes button clicked!');
};
</script>

// Expected rendered HTML (simplified)
<div>
  <button class="btn btn-secondary">Save Changes</button>
</div>
// Expected console output when clicked: "Save Changes button clicked!"

Example 3: Default Type

// In App.vue
<template>
  <div>
    <Button label="Just a Button" />
  </div>
</template>

// Expected rendered HTML (simplified)
<div>
  <button class="btn btn-primary">Just a Button</button>
</div>
// The type prop is not provided, so it defaults to 'primary'.

Constraints

  • You must use Vue 3 and TypeScript.
  • The Button component should be registered globally in main.ts.
  • Basic CSS styling should be applied to differentiate button types.
  • The click event must be emitted correctly.
  • The App.vue component should display at least three buttons of different types, including the default.

Notes

  • Consider how to organize your project. A good practice is to put global components in a dedicated folder (e.g., src/components/global).
  • Think about how you will pass props down to the Button component and how it will emit events back up.
  • The global registration can be done using app.component('ComponentName', Component).
  • For styling, you can define simple CSS classes like .btn, .btn-primary, .btn-secondary, and .btn-danger.
Loading editor...
typescript