📖 Scenario: You are building a simple Vue 3 component that emits a typed event when a button is clicked. This helps other components know exactly what data to expect from the event.
🎯 Goal: Create a Vue 3 component that emits a typed event called update with a string payload when a button is clicked.
📋 What You'll Learn
Create a Vue 3 component using the <script setup> syntax
Define the emits option with a typed update event that accepts a string
Add a button that triggers the update event with a specific string payload
Use TypeScript to ensure the event payload is typed correctly
💡 Why This Matters
🌍 Real World
Typed emits help Vue developers build components that communicate clearly and safely, reducing bugs caused by unexpected event data.
💼 Career
Understanding typed emits is important for Vue developers working on scalable applications where components need strict contracts for events.
Progress0 / 4 steps
1
Create the Vue component skeleton
Create a Vue 3 component file with <script setup lang="ts"> and an empty template section.
Vue
Hint
Start by creating the basic structure of a Vue 3 component using the <script setup> syntax with TypeScript.
2
Define the typed emits option
Inside the <script setup lang="ts">, define a constant called emit using defineEmits with an event named update that accepts a string payload.
Vue
Hint
Use defineEmits with a TypeScript type that specifies the event name and the payload type.
3
Add a button that emits the event
In the <template>, add a <button> element with a click event handler that calls emit('update', 'Hello Vue').
Vue
Hint
Use the @click directive on the button to call the emit function with the correct event name and string.
4
Complete the component with proper typing
Ensure the component uses defineEmits with the typed update event and the button emits the event with the string 'Hello Vue'. The component should be fully typed and ready to use.
Vue
Hint
Check that the emits typing and button click event are correctly implemented and match exactly.
Practice
(1/5)
1. What is the main purpose of using defineEmits in a Vue component?
easy
A. To declare which events the component can emit and their payload types
B. To define the component's reactive state variables
C. To register global Vue plugins
D. To import external libraries into the component
Solution
Step 1: Understand the role of defineEmits
defineEmits is used inside <script setup> to specify which events a component can send out.
Step 2: Identify what it declares
It declares event names and their payload types to improve type safety and tooling support.
Final Answer:
To declare which events the component can emit and their payload types -> Option A
Quick Check:
Typing emits = declare events and payloads [OK]
Hint: defineEmits declares events your component can send [OK]
Common Mistakes:
Confusing defineEmits with state or props
Thinking it registers plugins
Using it to import libraries
2. Which of the following is the correct syntax to type an emit event named submit with a payload of type string in Vue 3 <script setup>?
A. Missing payload argument when emitting 'save' event
B. Incorrect event name 'save' should be 'Save'
C. defineEmits should not use type annotations
D. emit function is not defined
Solution
Step 1: Check the typed emit signature
The save event expects a payload argument of type object.
Step 2: Analyze the emit call
The call emit('save') is missing the required payload argument, causing a type error.
Final Answer:
Missing payload argument when emitting 'save' event -> Option A
Quick Check:
Typed emits require payloads as declared [OK]
Hint: Emit calls must include all typed payload arguments [OK]
Common Mistakes:
Omitting required payload argument
Using wrong event name casing
Thinking type annotations are invalid here
5. You want to type a Vue component emit that can send either a string or number payload with the event name change. Which is the correct way to type this using defineEmits?
To allow multiple types for a payload, use a union type with |, e.g., string | number.
Step 2: Check the options for correct union usage
const emit = defineEmits<{ change: (value: string | number) => void }>() correctly types the change event with a payload that can be either string or number.
Step 3: Identify incorrect options
const emit = defineEmits<{ change: (value: string) => void; change: (value: number) => void }>() repeats the same event name twice, which is invalid. const emit = defineEmits<{ change: (value: string & number) => void }>() uses intersection & which means both types simultaneously (impossible). const emit = defineEmits<{ change: (value: any) => void }>() uses any which loses type safety.