📖 Scenario: You are building a Vue 3 application that manages a list of tasks for a team. As the app grows, you want to keep your code clean, reusable, and easy to maintain. Advanced Vue patterns help you organize your code better and avoid bugs.
🎯 Goal: Build a Vue 3 component that uses advanced patterns like the Composition API with ref, computed, and watch to manage tasks. You will also use a composable function to share logic and demonstrate how these patterns improve code clarity and reusability.
📋 What You'll Learn
Create a reactive list of tasks using ref
Add a configuration variable to filter tasks by completion status
Use a computed property to get filtered tasks
Use a composable function to encapsulate task management logic
💡 Why This Matters
🌍 Real World
In real projects, managing state and logic cleanly is vital as apps grow. Advanced Vue patterns like composables and computed properties help keep code easy to read and reuse.
💼 Career
Vue developers often use these patterns to build scalable, maintainable applications. Knowing them improves your ability to work on professional Vue projects.
Progress0 / 4 steps
1
Set up reactive task list
Create a Vue 3 component with the setup() function. Inside it, create a reactive variable called tasks using ref with this exact array of objects: [{ id: 1, title: 'Write report', completed: false }, { id: 2, title: 'Email client', completed: true }, { id: 3, title: 'Update website', completed: false }].
Vue
Hint
Use ref from Vue to make the tasks array reactive inside setup().
2
Add filter configuration
Inside the setup() function, create a reactive variable called showCompleted using ref and set it to false. This will control if completed tasks are shown.
Vue
Hint
Use ref(false) to create the showCompleted reactive variable.
3
Create computed filtered tasks
Inside setup(), create a computed property called filteredTasks that returns tasks filtered by showCompleted. If showCompleted.value is true, return all tasks; otherwise, return only tasks where completed is false.
Vue
Hint
Use computed from Vue and a ternary operator to filter tasks.
4
Use a composable for task logic
Create a composable function called useTasks outside the component that returns tasks, showCompleted, and filteredTasks. Then inside setup(), call useTasks() and use its returned values.
Vue
Hint
Define useTasks as a function returning the reactive variables and computed property. Then call it inside setup().
Practice
(1/5)
1. Why do advanced patterns like the Composition API matter in Vue apps?
easy
A. They remove the need for any JavaScript in Vue components.
B. They make the app run slower but look nicer.
C. They help organize code better and make it reusable across components.
D. They only work with Vue 2 and older versions.
Solution
Step 1: Understand the role of advanced patterns
Advanced patterns like the Composition API help organize code logically and improve reuse.
Step 2: Eliminate incorrect options
The other options wrongly claim advanced patterns remove JavaScript, make apps slower, or limit to Vue 2.
Final Answer:
They help organize code better and make it reusable across components. -> Option C
Quick Check:
Advanced patterns improve code clarity and reuse [OK]
Hint: Advanced patterns improve reuse and clarity in Vue code [OK]
Common Mistakes:
Thinking advanced patterns slow down the app
Confusing Vue 2 and Vue 3 features
Believing advanced patterns remove JavaScript
2. Which of the following is the correct syntax to define a composable function in Vue 3?
easy
A. function useCounter() { const count = ref(0); return { count }; }
B. const useCounter = () => { let count = 0; return count; }
C. function useCounter() { let count = 0; console.log(count); }
D. const useCounter = function() { count = ref(0); }
Solution
Step 1: Identify proper composable pattern
A composable returns reactive state like ref and exposes it for reuse.
Step 2: Check each option's correctness
function useCounter() { const count = ref(0); return { count }; } correctly uses ref and returns count. The others fail by returning plain numbers, only logging, or missing declarations/returns.
Final Answer:
function useCounter() { const count = ref(0); return { count }; } -> Option A
Quick Check:
Composable returns reactive state [OK]
Hint: Composable must return reactive refs or reactive objects [OK]
Common Mistakes:
Returning plain variables instead of refs
Not returning anything from the composable
Using non-reactive variables inside composables
3. Given this Vue 3 setup using a composable:
import { ref } from 'vue';
function useToggle() {
const isOn = ref(false);
function toggle() { isOn.value = !isOn.value; }
return { isOn, toggle };
}
const { isOn, toggle } = useToggle();
toggle();
toggle();
console.log(isOn.value);
What will be logged to the console?
medium
A. true
B. Error: isOn is not defined
C. undefined
D. false
Solution
Step 1: Trace the toggle function calls
Initially, isOn.value is false. First toggle flips it to true, second toggle flips it back to false.
Step 2: Determine final value logged
After two toggles, isOn.value is false, so console.log prints false.
Final Answer:
false -> Option D
Quick Check:
Two toggles flip false -> true -> false [OK]
Hint: Toggle flips boolean each call; two flips return to start [OK]
Common Mistakes:
Assuming toggle only runs once
Confusing ref.value with ref itself
Expecting undefined or error due to scope confusion
4. This Vue 3 composable code has a bug:
import { ref } from 'vue';
function useCounter() {
const count = ref(0);
function increment() {
count = count + 1;
}
return { count, increment };
}
What is the error and how to fix it?
medium
A. Missing return statement; fix by adding return count
B. Cannot reassign ref variable; fix by using count.value += 1
C. ref is not imported; fix by importing ref from 'vue'
D. increment function is not called; fix by calling increment() inside useCounter
Solution
Step 1: Identify the incorrect ref usage
Ref variables are objects; you must update their .value property, not reassign the ref itself.
Step 2: Correct the increment function
Change count = count + 1 to count.value += 1 to update the reactive value properly.
Final Answer:
Cannot reassign ref variable; fix by using count.value += 1 -> Option B
Quick Check:
Update ref.value, not ref itself [OK]
Hint: Update .value of ref, never reassign the ref variable [OK]
Common Mistakes:
Reassigning the ref variable instead of its .value
Forgetting to import ref
Not returning reactive state from composable
5. You want to create a reusable composable that filters a list of items reactively based on a search term. Which advanced pattern best helps keep your Vue app clean and efficient?
hard
A. Use a composable with reactive refs for the list and search term, returning a computed filtered list.
B. Write the filtering logic directly inside each component's template using v-for and v-if.
C. Store the filtered list in a global variable outside Vue's reactivity system.
D. Use watchers to manually update the DOM elements for filtering.
Solution
Step 1: Identify the best pattern for reusable reactive filtering
A composable with reactive refs and computed properties encapsulates logic cleanly and allows reuse.
Step 2: Evaluate other options for drawbacks
Duplicating logic in templates, using non-reactive globals, or manual DOM updates are less efficient and clean.
Final Answer:
Use a composable with reactive refs for the list and search term, returning a computed filtered list. -> Option A