Discover how a simple function can save you hours of repetitive work and bugs!
Why Composables for reusable logic in Vue? - Purpose & Use Cases
Imagine you write the same code to handle user input validation in multiple Vue components. Every time you want to change the logic, you must update it in many places.
Copying and pasting code everywhere makes your app hard to maintain. It's easy to forget one spot, causing bugs. It also wastes time and clutters your components.
Composables let you write reusable logic once and share it across components. You keep your code clean, easy to update, and components focused on UI.
function validate() { /* repeated in many components */ }export function useValidation() { /* reusable logic here */ }You can build cleaner, more maintainable Vue apps by sharing logic easily without repeating yourself.
Imagine a form validation logic used in signup, login, and profile update forms—all using the same composable to keep validation consistent.
Manual code repetition causes bugs and wastes time.
Composables let you share logic cleanly across components.
This makes your app easier to maintain and update.
Practice
composable in Vue?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 AQuick Check:
Composable = reusable logic [OK]
- Confusing composables with CSS or templates
- Thinking composables register components
- Assuming composables create directives
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 DQuick Check:
Composable = function returning reactive state [OK]
- Defining composables as Vue instances
- Returning reactive objects without a function
- Not using ref or reactive inside composables
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?Solution
Step 1: Analyze initial state and toggle function
Initially,isOn.valueis 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 CQuick Check:
Two toggles flip false twice back to false [OK]
- Assuming toggle sets true always
- Forgetting to access .value of ref
- Confusing initial state with toggled state
import { ref } from 'vue';
export function useCount() {
const count = ref(0);
function increment() {
count++;
}
return { count, increment };
}Solution
Step 1: Understand ref usage
Ref values are accessed and mutated via the.valueproperty.Step 2: Identify error in increment function
The code usescount++which tries to increment the ref object itself, not its value. It should becount.value++.Final Answer:
You cannot increment a ref directly with ++ operator -> Option BQuick Check:
Use count.value++ to update ref [OK]
- Incrementing ref without .value
- Confusing reactive and ref imports
- Thinking function name affects behavior
Solution
Step 1: Understand reactive window width tracking
We need a ref to hold width and update it on resize events.Step 2: Check event listener lifecycle management
function useWindowWidth() { const width = ref(window.innerWidth); onMounted(() => { window.addEventListener('resize', () => { width.value = window.innerWidth; }); }); onUnmounted(() => { window.removeEventListener('resize', () => { width.value = window.innerWidth; }); }); return { width }; } correctly adds listener on mount and removes it on unmount to avoid leaks. function useWindowWidth() { const width = ref(window.innerWidth); window.addEventListener('resize', () => { width.value = window.innerWidth; }); return { width }; } adds listener immediately without cleanup. function useWindowWidth() { const width = reactive({ value: window.innerWidth }); window.onresize = () => { width.value = window.innerWidth; }; return width; } uses reactive incorrectly and overwrites window.onresize. function useWindowWidth() { const width = ref(0); window.addEventListener('resize', () => { width = window.innerWidth; }); return { width }; } tries to assign to ref variable directly, which is invalid.Final Answer:
function useWindowWidth() { const width = ref(window.innerWidth); onMounted(() => { window.addEventListener('resize', () => { width.value = window.innerWidth; }); }); onUnmounted(() => { window.removeEventListener('resize', () => { width.value = window.innerWidth; }); }); return { width }; } -> Option AQuick Check:
Manage listeners with lifecycle hooks [OK]
- Not removing event listeners causing memory leaks
- Assigning directly to ref variable instead of .value
- Overwriting window.onresize instead of adding listener
Ready to prove it?
Pass the test and this pattern moves unknown
