Hone logo
Hone
Problems

Vue Props Definition with TypeScript

This challenge focuses on correctly defining props for a Vue component using TypeScript. Mastering props is crucial for building reusable and maintainable Vue applications, as they are the primary mechanism for passing data from a parent component to a child component.

Problem Description

Your task is to create a robust props definition for a Vue 3 component that accepts and validates various types of data. The component is designed to display user profile information, including their name, age, and an optional avatar URL.

Key Requirements:

  1. Define props using TypeScript: The props object should be typed to leverage TypeScript's static typing capabilities.
  2. Support primitive types: The name prop should be a required string, and the age prop should be a required number.
  3. Support optional reference types: The avatarUrl prop should be an optional string. If not provided, a default value should be used.
  4. Implement custom validation: For the age prop, implement a custom validator to ensure the age is a non-negative number.
  5. Use defineProps macro: Utilize the <script setup> syntax with the defineProps macro.

Expected Behavior:

  • The component should correctly receive and display the name and age.
  • If avatarUrl is provided, it should be used; otherwise, a default placeholder image URL should be rendered.
  • If a negative number is passed for age, the component should not render (or indicate an error, depending on implementation, but for this challenge, assume it simply won't render the relevant parts of the profile).

Examples

Example 1: Basic Usage

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

const props = defineProps({
  name: {
    type: String,
    required: true,
  },
  age: {
    type: Number,
    required: true,
    validator: (value: number) => value >= 0,
  },
  avatarUrl: {
    type: String,
    required: false,
    default: 'https://example.com/default-avatar.png',
  },
});
</script>

<template>
  <div>
    <img :src="props.avatarUrl" alt="Avatar" width="50" height="50">
    <h2>{{ props.name }}</h2>
    <p>Age: {{ props.age }}</p>
  </div>
</template>

Parent Component Usage:

<template>
  <UserProfile
    name="Alice Smith"
    :age="30"
    avatarUrl="https://example.com/alice.jpg"
  />
</template>

<script setup lang="ts">
import UserProfile from './UserProfile.vue';
</script>

Output (Rendered HTML Snippet):

<div>
  <img src="https://example.com/alice.jpg" alt="Avatar" width="50" height="50">
  <h2>Alice Smith</h2>
  <p>Age: 30</p>
</div>

Explanation: All props are provided correctly, and the component renders with the provided data.

Example 2: Missing Optional Prop

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

// ... (same props definition as Example 1) ...
</script>

<template>
  <!-- ... (same template as Example 1) ... -->
</template>

Parent Component Usage:

<template>
  <UserProfile
    name="Bob Johnson"
    :age="25"
  />
</template>

<script setup lang="ts">
import UserProfile from './UserProfile.vue';
</script>

Output (Rendered HTML Snippet):

<div>
  <img src="https://example.com/default-avatar.png" alt="Avatar" width="50" height="50">
  <h2>Bob Johnson</h2>
  <p>Age: 25</p>
</div>

Explanation: The avatarUrl prop is not provided, so the default value is used.

Example 3: Invalid Prop Value (Custom Validator)

Parent Component Usage:

<template>
  <UserProfile
    name="Charlie Brown"
    :age="-5"
    avatarUrl="https://example.com/charlie.png"
  />
</template>

<script setup lang="ts">
import UserProfile from './UserProfile.vue';
</script>

Expected Behavior: When this parent component is used, the UserProfile component will not render its content because the age prop fails the custom validator (age must be >= 0). In a real application, you might see a Vue warning in the console indicating the prop validation failure. For this challenge, consider that the component's template logic might conditionally render based on valid props. For simplicity, assume the template won't render if validation fails.

Constraints

  • The props definition must be within a <script setup> block using lang="ts".
  • The defineProps macro must be used.
  • All required props must be explicitly marked as required: true.
  • The custom validator for age must return true if the value is valid, and false otherwise.
  • The avatarUrl prop must have a default value.

Notes

  • Consider the TypeScript types when defining your props. Vue 3's defineProps can infer types from an array of strings or a single string, but for more complex scenarios like custom validators and default values, the object syntax is preferred and more explicit.
  • Think about how prop validation errors are handled in Vue. While you don't need to implement explicit error handling in the component's template for this challenge, understanding that validation failures occur is important.
  • The validator function receives the value being passed to the prop.
Loading editor...
typescript