Bird
Raised Fist0
Vueframework~10 mins

Creating a custom composable in Vue - Interactive Practice

Choose your learning style10 modes available
Practice - 5 Tasks
Answer the questions below
1fill in blank
easy

Complete the code to import the Vue Composition API function needed to create a reactive reference.

Vue
import { [1] } from 'vue';
Drag options to blanks, or click blank then click option'
Aref
Breactive
Ccomputed
Dwatch
Attempts:
3 left
💡 Hint
Common Mistakes
Using reactive instead of ref
Using computed when ref is needed
2fill in blank
medium

Complete the code to define a custom composable that returns a reactive count and an increment function.

Vue
export function useCounter() {
  const count = [1](0);
  function increment() {
    count.value++;
  }
  return { count, increment };
}
Drag options to blanks, or click blank then click option'
Aref
Bwatch
Ccomputed
Dreactive
Attempts:
3 left
💡 Hint
Common Mistakes
Using reactive instead of ref for a primitive value
Forgetting to use .value when incrementing
3fill in blank
hard

Fix the error in the composable by completing the code to watch the count and log changes.

Vue
import { ref, watch } from 'vue';

export function useCounterLogger() {
  const count = ref(0);
  watch(count, (newVal, oldVal) => {
    console.log('Count changed from', [1], 'to', newVal);
  });
  function increment() {
    count.value++;
  }
  return { count, increment };
}
Drag options to blanks, or click blank then click option'
AnewVal.value
Bcount.value
ColdVal.value
DoldVal
Attempts:
3 left
💡 Hint
Common Mistakes
Using .value on oldVal causing undefined errors
Logging count.value instead of oldVal
4fill in blank
hard

Fill both blanks to create a composable that returns a reactive message and a function to update it.

Vue
import { [1], [2] } from 'vue';

export function useMessage() {
  const message = ref('Hello');
  function updateMessage(newMsg) {
    message.value = newMsg;
  }
  return { message, updateMessage };
}
Drag options to blanks, or click blank then click option'
Aref
Breactive
Ccomputed
Dwatch
Attempts:
3 left
💡 Hint
Common Mistakes
Importing computed or watch instead of reactive
Forgetting to import ref
5fill in blank
hard

Fill all three blanks to create a composable that returns a reactive count, an increment function, and a computed double count.

Vue
import { [1], [2], [3] } from 'vue';

export function useAdvancedCounter() {
  const count = ref(0);
  function increment() {
    count.value++;
  }
  const doubleCount = computed(() => count.value * 2);
  return { count, increment, doubleCount };
}
Drag options to blanks, or click blank then click option'
Aref
Bcomputed
Cwatch
Dreactive
Attempts:
3 left
💡 Hint
Common Mistakes
Mixing up order of imports
Forgetting to import computed

Practice

(1/5)
1. What is the main purpose of creating a custom composable in Vue?
easy
A. To define global CSS styles
B. To reuse reactive logic across multiple components
C. To create new Vue directives
D. To register components globally

Solution

  1. Step 1: Understand what composables do

    Custom composables are functions that encapsulate reactive logic to be reused.
  2. Step 2: Identify the purpose in Vue components

    They help share logic without repeating code in multiple components.
  3. Final Answer:

    To reuse reactive logic across multiple components -> Option B
  4. Quick Check:

    Reusable reactive logic = B [OK]
Hint: Composables = reusable reactive logic functions [OK]
Common Mistakes:
  • Confusing composables with styling or directives
  • Thinking composables register components
  • Assuming composables handle templates
2. Which of the following is the correct way to start a custom composable function in Vue 3?
easy
A. function useData() { const count = ref(0); return { count }; }
B. const useData = () => { const count = reactive(0); return count; }
C. function useData() { const count = ref(0); }
D. const useData = () => { return ref({ count: 0 }); }

Solution

  1. Step 1: Check function declaration and return

    function useData() { const count = ref(0); return { count }; } declares a function named with 'use' prefix and returns reactive refs.
  2. Step 2: Validate reactive usage and return object

    function useData() { const count = ref(0); return { count }; } returns an object with the reactive ref, which is correct pattern.
  3. Final Answer:

    function useData() { const count = ref(0); return { count }; } -> Option A
  4. Quick Check:

    Composable returns reactive refs in object = D [OK]
Hint: Composable must return reactive data inside an object [OK]
Common Mistakes:
  • Not returning reactive data
  • Returning reactive primitive directly instead of object
  • Missing 'use' prefix in function name
3. Given this composable code, what will be logged when calling increment() twice?
import { ref } from 'vue';

export function useCounter() {
  const count = ref(0);
  function increment() {
    count.value++;
    console.log(count.value);
  }
  return { count, increment };
}
medium
A. Undefined and then 1
B. 0 and then 1
C. 2 and then 3
D. 1 and then 2

Solution

  1. Step 1: Understand initial count value

    The count starts at 0 as a ref.
  2. Step 2: Trace increment calls and console logs

    Each increment increases count.value by 1 and logs it immediately.
  3. Final Answer:

    1 and then 2 -> Option D
  4. Quick Check:

    Increment twice logs 1 then 2 [OK]
Hint: Ref value increments and logs immediately [OK]
Common Mistakes:
  • Confusing ref.value with ref itself
  • Assuming count starts at 1
  • Thinking console logs before increment
4. Identify the error in this composable code:
import { ref } from 'vue';

export function useToggle() {
  const state = ref(false);
  function toggle() {
    state = !state;
  }
  return { state, toggle };
}
medium
A. ref should be reactive instead
B. Missing return statement
C. Cannot reassign a const ref variable directly
D. toggle function should be async

Solution

  1. Step 1: Check how ref is updated

    The code tries to assign 'state = !state', which reassigns the const variable.
  2. Step 2: Correct way to update ref value

    Should update 'state.value = !state.value' instead of reassigning 'state'.
  3. Final Answer:

    Cannot reassign a const ref variable directly -> Option C
  4. Quick Check:

    Update ref.value, not ref variable [OK]
Hint: Update ref.value, never reassign ref variable [OK]
Common Mistakes:
  • Reassigning ref variable instead of its value
  • Forgetting to use .value to access ref
  • Assuming reactive is needed instead of ref
5. You want to create a composable that fetches user data and exposes loading state. Which approach correctly combines reactive state and async fetch inside a composable?
hard
A. function useUser() { const user = ref(null); const loading = ref(true); async function fetchUser() { loading.value = true; user.value = await fetch('/api/user').then(r => r.json()); loading.value = false; } fetchUser(); return { user, loading }; }
B. function useUser() { const user = reactive(null); const loading = false; async function fetchUser() { loading = true; user = await fetch('/api/user').then(r => r.json()); loading = false; } fetchUser(); return { user, loading }; }
C. function useUser() { const user = ref(null); const loading = ref(false); function fetchUser() { loading.value = true; fetch('/api/user').then(r => r.json()).then(data => { user.value = data; loading.value = false; }); } return { user, loading, fetchUser }; }
D. function useUser() { const user = ref(null); const loading = ref(true); fetch('/api/user').then(r => r.json()).then(data => { user = data; loading.value = false; }); return { user, loading }; }

Solution

  1. Step 1: Check reactive state initialization

    function useUser() { const user = ref(null); const loading = ref(true); async function fetchUser() { loading.value = true; user.value = await fetch('/api/user').then(r => r.json()); loading.value = false; } fetchUser(); return { user, loading }; } correctly uses ref for user and loading states.
  2. Step 2: Verify async fetch and state updates

    function useUser() { const user = ref(null); const loading = ref(true); async function fetchUser() { loading.value = true; user.value = await fetch('/api/user').then(r => r.json()); loading.value = false; } fetchUser(); return { user, loading }; } uses async function to set loading true, await fetch, then set loading false.
  3. Step 3: Confirm fetch is called inside composable

    function useUser() { const user = ref(null); const loading = ref(true); async function fetchUser() { loading.value = true; user.value = await fetch('/api/user').then(r => r.json()); loading.value = false; } fetchUser(); return { user, loading }; } calls fetchUser() immediately to start loading data.
  4. Final Answer:

    function useUser() { const user = ref(null); const loading = ref(true); async function fetchUser() { loading.value = true; user.value = await fetch('/api/user').then(r => r.json()); loading.value = false; } fetchUser(); return { user, loading }; } -> Option A
  5. Quick Check:

    Async fetch with reactive refs = A [OK]
Hint: Use ref for state and async function with await inside composable [OK]
Common Mistakes:
  • Reassigning reactive or ref variables directly
  • Not using async/await properly
  • Not updating loading state correctly
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard