Bird
Raised Fist0
Vueframework~10 mins

Composable with reactive state in Vue - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Composable with reactive state
Define reactive state inside composable
↓
Return reactive state and functions
↓
Import composable in component
↓
Use reactive state in component template
↓
Update state via composable functions
↓
Component re-renders with new state
This flow shows how a composable defines reactive state and functions, which a component imports and uses to reactively update its UI.
Execution Sample
Vue
import { ref } from 'vue'

export function useCounter() {
  const count = ref(0)
  function increment() { count.value++ }
  return { count, increment }
}
Defines a composable that holds a reactive count and an increment function.
Execution Table
StepActionReactive State (count.value)Function CalledComponent Render Output
1Composable useCounter() called0nonecount: 0
2increment() called1incrementcount: 1
3increment() called2incrementcount: 2
4No more calls2nonecount: 2
💡 No more function calls; reactive state remains at 2; component shows updated count.
Variable Tracker
VariableStartAfter 1After 2Final
count.value0122
Key Moments - 2 Insights
Why does the component update its display when count.value changes?
Because count is a reactive ref, Vue tracks its usage in the component and triggers re-render when count.value changes, as shown in execution_table steps 2 and 3.
What happens if we call increment() multiple times quickly?
Each call increases count.value by 1, and Vue batches updates to re-render efficiently, reflected in variable_tracker and execution_table rows 2 and 3.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution table, what is count.value after step 2?
A1
B0
C2
Dundefined
💡 Hint
Check the 'Reactive State (count.value)' column at step 2 in the execution_table.
At which step does the component first show count: 2?
AStep 1
BStep 2
CStep 3
DStep 4
💡 Hint
Look at the 'Component Render Output' column in the execution_table.
If increment() was never called, what would the component display?
Acount: 1
Bcount: 0
Ccount: undefined
Dcount: null
💡 Hint
Refer to step 1 in execution_table where no functions are called yet.
Concept Snapshot
Composable with reactive state:
- Use Vue's ref() to create reactive state inside composable.
- Return state and functions from composable.
- Import and use composable in component.
- Component auto-updates when reactive state changes.
- Enables clean, reusable logic with reactive data.
Full Transcript
This visual execution trace shows how a Vue composable manages reactive state. First, the composable defines a reactive variable 'count' using ref(0). It also defines an increment function that increases count.value by one. When the composable is used in a component, the component accesses count and increment. Calling increment updates count.value, which Vue tracks reactively. This triggers the component to re-render and display the updated count. The execution table shows each step: initial state zero, then increments to one and two, with the component output updating accordingly. The variable tracker confirms count.value changes over time. Key moments clarify why Vue updates the UI automatically and how multiple increments behave. The quiz tests understanding of state changes and rendering steps. This pattern helps keep logic reusable and reactive in Vue apps.

Practice

(1/5)
1. What is the main purpose of a composable function in Vue 3?
easy
A. To create new Vue components automatically
B. To define global CSS styles for the app
C. To replace the Vue router functionality
D. To reuse reactive state and logic across multiple components

Solution

  1. Step 1: Understand composable function role

    Composable functions are designed to share reactive state and logic so multiple components can use them without repeating code.
  2. Step 2: Eliminate unrelated options

    Creating new Vue components automatically, defining global CSS styles for the app, and replacing the Vue router functionality are all unrelated to composables.
  3. Final Answer:

    To reuse reactive state and logic across multiple components -> Option D
  4. Quick Check:

    Composable = reusable reactive logic [OK]
Hint: Composable = reusable reactive logic across components [OK]
Common Mistakes:
  • Confusing composables with components
  • Thinking composables handle styling or routing
  • Assuming composables create UI elements
2. Which of the following is the correct way to create a reactive state inside a composable using Vue 3 Composition API?
easy
A. const count = reactive(0)
B. const count = ref(0)
C. const count = reactive({ value: 0 })
D. const count = ref({ value: 0 })

Solution

  1. Step 1: Recall ref and reactive usage

    ref is used to create a reactive primitive like a number, string, or boolean. reactive is for objects.
  2. Step 2: Analyze options

    const count = ref(0) correctly uses ref(0) for a reactive number. const count = reactive(0) is invalid because reactive expects an object, not a primitive. const count = reactive({ value: 0 }) wraps a number in an object but is less common for simple primitives. const count = ref({ value: 0 }) uses ref with an object, which works but is less idiomatic than reactive for objects.
  3. Final Answer:

    const count = ref(0) -> Option B
  4. Quick Check:

    Primitive reactive state uses ref() [OK]
Hint: Use ref() for primitives, reactive() for objects [OK]
Common Mistakes:
  • Using reactive() with primitive values
  • Using ref() for complex objects instead of reactive()
  • Confusing ref({}) and reactive({}) usage
3. Given this composable code, what will be logged when increment() is called twice and then count.value is logged?
import { ref } from 'vue';
export function useCounter() {
  const count = ref(0);
  function increment() {
    count.value++;
  }
  return { count, increment };
}

const { count, increment } = useCounter();
increment();
increment();
console.log(count.value);
medium
A. 2
B. 0
C. 1
D. undefined

Solution

  1. Step 1: Understand initial state and increments

    The count starts at 0. Each call to increment() increases count.value by 1.
  2. Step 2: Calculate final value after two increments

    After two calls, count.value = 0 + 1 + 1 = 2.
  3. Final Answer:

    2 -> Option A
  4. Quick Check:

    Two increments add 2 to count.value [OK]
Hint: Increment ref.value to update reactive count [OK]
Common Mistakes:
  • Forgetting to access .value on ref
  • Assuming count is a plain number, not ref
  • Confusing initial value with updated value
4. Identify the error in this composable code snippet:
import { reactive } from 'vue';
export function useUser() {
  const user = reactive({ name: 'Alice', age: 30 });
  function updateName(newName) {
    user.name = newName;
  }
  return { user, updateName };
}

const { user, updateName } = useUser();
updateName('Bob');
console.log(user.name);
medium
A. No error, code works correctly
B. Cannot assign to reactive object properties directly
C. updateName function is not returned
D. Missing import of ref

Solution

  1. Step 1: Check reactive object usage

    The user object is created with reactive and its properties can be updated directly.
  2. Step 2: Verify function and return

    The updateName function updates user.name correctly and is returned for use.
  3. Final Answer:

    No error, code works correctly -> Option A
  4. Quick Check:

    Reactive objects allow direct property assignment [OK]
Hint: reactive objects allow direct property changes [OK]
Common Mistakes:
  • Thinking reactive properties are read-only
  • Forgetting to return functions from composable
  • Confusing ref and reactive usage
5. You want to create a composable that tracks a list of tasks reactively and provides a function to add a new task only if it is not empty. Which of the following implementations correctly achieves this?
hard
A. import { ref } from 'vue'; export function useTasks() { const tasks = ref([]); function addTask(task) { tasks.push(task); } return { tasks, addTask }; }
B. import { reactive } from 'vue'; export function useTasks() { const tasks = reactive([]); function addTask(task) { if (task) tasks.value.push(task); } return { tasks, addTask }; }
C. import { ref } from 'vue'; export function useTasks() { const tasks = ref([]); function addTask(task) { if (task) tasks.value.push(task); } return { tasks, addTask }; }
D. import { reactive } from 'vue'; export function useTasks() { const tasks = reactive([]); function addTask(task) { if (task.length > 0) tasks.value.push(task); } return { tasks, addTask }; }

Solution

  1. Step 1: Choose correct reactive type for array

    Arrays as reactive state are best handled with ref([]) so we access the array via tasks.value.
  2. Step 2: Validate addTask function logic

    import { ref } from 'vue'; export function useTasks() { const tasks = ref([]); function addTask(task) { if (task) tasks.value.push(task); } return { tasks, addTask }; } checks if task is truthy (not empty) before pushing to tasks.value, which is correct. import { reactive } from 'vue'; export function useTasks() { const tasks = reactive([]); function addTask(task) { if (task) tasks.value.push(task); } return { tasks, addTask }; } uses reactive([]) but incorrectly accesses tasks.value.push(task) since reactive does not have a value property. import { ref } from 'vue'; export function useTasks() { const tasks = ref([]); function addTask(task) { tasks.push(task); } return { tasks, addTask }; } pushes without checking if task is empty. import { reactive } from 'vue'; export function useTasks() { const tasks = reactive([]); function addTask(task) { if (task.length > 0) tasks.value.push(task); } return { tasks, addTask }; } incorrectly tries to access tasks.value when tasks is reactive, which does not have a value property.
  3. Final Answer:

    use ref([]) with if (task) tasks.value.push(task) -> Option C
  4. Quick Check:

    Use ref([]) for arrays and check input before push [OK]
Hint: Use ref([]) for reactive arrays and check input before push [OK]
Common Mistakes:
  • Using reactive([]) for arrays instead of ref([])
  • Forgetting to check if task is empty
  • Accessing .value on reactive arrays
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