Hone logo
Hone
Problems

Vue Global Component Registration

This challenge focuses on understanding and implementing global component registration in Vue.js using TypeScript. Global components are essential for creating reusable UI elements that can be used across your entire application without the need for explicit import and registration in every parent component.

Problem Description

Your task is to create a set of reusable Vue components and register them globally so they can be used anywhere within a Vue application without explicit imports in child components.

What needs to be achieved:

  1. Create two distinct Vue components: a PrimaryButton and a ModalDialog.
  2. Register these components globally within a Vue application.
  3. Demonstrate their usage in a parent component.

Key requirements:

  • The PrimaryButton component should accept a label prop (string) and emit a click event when clicked.
  • The ModalDialog component should accept a title prop (string) and a visible prop (boolean). It should also have a default slot for content and emit a close event when a "close" button within the modal is clicked.
  • Global registration should be handled in the main application setup file (e.g., main.ts).
  • The solution should be implemented using TypeScript.

Expected behavior: When the Vue application is rendered, the PrimaryButton should display its label and, upon clicking, trigger an action. The ModalDialog should be conditionally rendered based on the visible prop, display its title, and allow content to be placed inside its slot. A close button within the modal should correctly emit the close event.

Any important edge cases to consider:

  • What happens if the label prop for PrimaryButton is not provided?
  • How does the ModalDialog handle its visible state changes from the parent?
  • Ensure proper type safety with TypeScript for props and events.

Examples

Example 1: PrimaryButton Usage

<!-- ParentComponent.vue -->
<template>
  <div>
    <PrimaryButton label="Click Me!" @click="handleClick" />
  </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue';

export default defineComponent({
  name: 'ParentComponent',
  methods: {
    handleClick() {
      alert('Button clicked!');
    }
  }
});
</script>

Output: A button with the text "Click Me!" is displayed. Clicking it triggers an alert.

Example 2: ModalDialog Usage

<!-- ParentComponent.vue -->
<template>
  <div>
    <PrimaryButton label="Open Modal" @click="showModal = true" />
    <ModalDialog title="My Modal" :visible="showModal" @close="showModal = false">
      <p>This is the content of the modal.</p>
    </ModalDialog>
  </div>
</template>

<script lang="ts">
import { defineComponent, ref } from 'vue';

export default defineComponent({
  name: 'ParentComponent',
  setup() {
    const showModal = ref(false);
    return {
      showModal
    };
  }
});
</script>

Output: A button "Open Modal" is displayed. Clicking it reveals a modal with the title "My Modal" and the text "This is the content of the modal.". A close button in the modal allows hiding it.

Example 3: Global Registration Demonstration Assume main.ts contains the global registration code.

// main.ts
import { createApp } from 'vue';
import App from './App.vue';
import PrimaryButton from './components/PrimaryButton.vue';
import ModalDialog from './components/ModalDialog.vue';

const app = createApp(App);

// Global registration
app.component('PrimaryButton', PrimaryButton);
app.component('ModalDialog', ModalDialog);

app.mount('#app');

Output: Any component within the App.vue hierarchy can now use <PrimaryButton> and <ModalDialog> without importing them directly.

Constraints

  • Vue.js 3.x should be used.
  • TypeScript must be used for all component definitions and application setup.
  • The global registration should occur in the main.ts (or equivalent entry point) file.
  • No third-party UI libraries should be used for the components themselves.

Notes

  • Consider using Vue's Composition API with <script setup> for a modern approach, but Function API is also acceptable.
  • Pay close attention to prop types and emitted event types for robust TypeScript integration.
  • Think about how you would structure your component files within a typical Vue project.
  • The goal is to understand the app.component() method and its implications for component availability.
Loading editor...
typescript