📖 Scenario: You are building a Vue 3 app that needs to track a counter value and allow incrementing it. You want to reuse this counting logic in multiple components without repeating code.
🎯 Goal: Create a composable function that holds the counter state and an increment function. Then use this composable inside a Vue component to display and update the counter.
📋 What You'll Learn
Create a composable function named useCounter that returns a reactive counter and an increment function
Use Vue's ref to create the counter state inside the composable
Create a Vue component that imports and uses useCounter
Display the counter value and add a button to increment it using the composable's function
💡 Why This Matters
🌍 Real World
Composables help you keep your Vue app code clean by putting reusable logic in one place. This is like having a shared tool you can use in many parts of your app.
💼 Career
Knowing how to write and use composables is important for Vue developers. It shows you can write modular, maintainable code that scales well in real projects.
Progress0 / 4 steps
1
Create the composable function with counter state
Create a composable function called useCounter that uses Vue's ref to create a reactive variable named count initialized to 0. Export this function.
Vue
Hint
Use ref(0) to create a reactive count variable inside useCounter.
2
Add an increment function inside the composable
Inside the useCounter function, add a function named increment that increases count.value by 1. Return increment along with count.
Vue
Hint
Define increment as a function that adds 1 to count.value.
3
Create a Vue component that uses the composable
Create a Vue component using <script setup>. Import useCounter from the composable file. Call useCounter() and destructure count and increment. Display count in a <p> and add a <button> that calls increment on click.
Vue
Hint
Use import { useCounter } from './useCounter' and call it inside <script setup>.
4
Complete the component with proper export and template
Ensure the Vue component uses the <script setup> syntax with the import and composable call. The template must have a <p> showing count and a <button> with @click calling increment. This completes the reusable logic and UI.
Vue
Hint
Make sure the component uses <script setup> and the template shows the count and increment button.
Practice
(1/5)
1. What is the main purpose of a composable in Vue?
easy
A. To reuse reactive logic across multiple components
B. To define global CSS styles
C. To create new Vue directives
D. To register Vue components globally
Solution
Step 1: Understand composables role
Composables are functions that encapsulate reactive logic to be reused.
Step 2: Identify main purpose
They help share logic like state or effects across components without duplication.
Final Answer:
To reuse reactive logic across multiple components -> Option A
Quick Check:
Composable = reusable logic [OK]
Hint: Composables share logic, not styles or components [OK]
Common Mistakes:
Confusing composables with CSS or templates
Thinking composables register components
Assuming composables create directives
2. Which of the following is the correct way to define a composable in Vue 3?
easy
A. function useCounter() { return reactive({ count: 0 }) }
B. const useCounter = new Vue({ data() { return { count: 0 } } })
C. const useCounter = reactive({ count: 0 })
D. function useCounter() { const count = ref(0); return { count }; }
Solution
Step 1: Check composable function syntax
A composable is a function that returns reactive state or methods.
Step 2: Validate options
function useCounter() { const count = ref(0); return { count }; } defines a function returning a ref wrapped count, which is correct. const useCounter = new Vue({ data() { return { count: 0 } } }) wrongly uses Vue instance syntax. const useCounter = reactive({ count: 0 }) returns reactive object directly without function. function useCounter() { return reactive({ count: 0 }) } returns reactive but misses ref usage and best practice.
Final Answer:
function useCounter() { const count = ref(0); return { count }; } -> Option D
Quick Check:
Composable = function returning reactive state [OK]
Hint: Composable must be a function returning reactive data [OK]
Common Mistakes:
Defining composables as Vue instances
Returning reactive objects without a function
Not using ref or reactive inside composables
3. Given this composable:
import { ref } from 'vue';
export function useToggle() {
const isOn = ref(false);
function toggle() { isOn.value = !isOn.value; }
return { isOn, toggle };
}
What will be the value of isOn.value after calling toggle() twice starting from initial state?
medium
A. true
B. undefined
C. false
D. null
Solution
Step 1: Analyze initial state and toggle function
Initially, isOn.value is false. Each toggle flips it to the opposite.
Step 2: Apply two toggles
First toggle: false -> true. Second toggle: true -> false.
Final Answer:
false -> Option C
Quick Check:
Two toggles flip false twice back to false [OK]
Hint: Toggle flips boolean; even toggles return original [OK]
Common Mistakes:
Assuming toggle sets true always
Forgetting to access .value of ref
Confusing initial state with toggled state
4. What is wrong with this composable code?
import { ref } from 'vue';
export function useCount() {
const count = ref(0);
function increment() {
count++;
}
return { count, increment };
}
medium
A. The count variable should be declared with reactive()
B. You cannot increment a ref directly with ++ operator
C. ref should be imported from 'vue/reactive' instead
D. The function should be named useCounter, not useCount
Solution
Step 1: Understand ref usage
Ref values are accessed and mutated via the .value property.
Step 2: Identify error in increment function
The code uses count++ which tries to increment the ref object itself, not its value. It should be count.value++.
Final Answer:
You cannot increment a ref directly with ++ operator -> Option B
Quick Check:
Use count.value++ to update ref [OK]
Hint: Always use .value to read or write ref values [OK]
Common Mistakes:
Incrementing ref without .value
Confusing reactive and ref imports
Thinking function name affects behavior
5. You want to create a composable that tracks window width and updates reactively on resize. Which approach correctly implements this?