Bird
Raised Fist0
Vueframework~10 mins

Readonly for immutable reactive data in Vue - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Readonly for immutable reactive data
Create reactive data
↓
Wrap with readonly()
↓
Use readonly data in template or logic
↓
Attempt to modify readonly data
↓
Vue warns and blocks mutation
↓
Data remains unchanged
This flow shows how Vue creates reactive data, wraps it as readonly to prevent changes, and blocks any mutation attempts while keeping data reactive.
Execution Sample
Vue
import { reactive, readonly } from 'vue';
const state = reactive({ count: 0 });
const readOnlyState = readonly(state);
readOnlyState.count = 5; // blocked
console.log(readOnlyState.count);
This code creates reactive state, wraps it as readonly, tries to change it (which is blocked), and logs the unchanged value.
Execution Table
StepActionValue BeforeAttempted ChangeResultValue After
1Create reactive stateN/AN/Astate = { count: 0 } reactive{ count: 0 }
2Wrap state with readonly(){ count: 0 }N/AreadOnlyState is readonly proxy{ count: 0 }
3Attempt to set readOnlyState.count = 5{ count: 0 }count = 5Mutation blocked, warning shown{ count: 0 }
4Read readOnlyState.count{ count: 0 }N/AReturns 00
💡 Mutation blocked by readonly proxy, so value remains unchanged
Variable Tracker
VariableStartAfter Step 1After Step 2After Step 3Final
stateundefined{ count: 0 } reactive{ count: 0 } reactive{ count: 0 } reactive{ count: 0 } reactive
readOnlyStateundefinedundefinedreadonly proxy of statereadonly proxy of statereadonly proxy of state
Key Moments - 2 Insights
Why can't we change the value of readOnlyState.count even though state is reactive?
Because readOnlyState is a readonly proxy that blocks any mutation attempts, as shown in step 3 of the execution_table where the mutation is blocked and a warning is shown.
Does readonly() make the data non-reactive?
No, readonly() keeps the data reactive but prevents changes. The value can still be read and will update if the original reactive state changes.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what is the value of readOnlyState.count after step 3?
A5
Bundefined
C0
DError
💡 Hint
Check the 'Value After' column in step 3 of the execution_table
At which step does Vue block the mutation attempt?
AStep 3
BStep 2
CStep 1
DStep 4
💡 Hint
Look at the 'Result' column describing mutation blocking
If we change the original state.count to 10, what happens to readOnlyState.count?
AIt stays 0
BIt updates to 10
CIt becomes readonly and stops updating
DIt throws an error
💡 Hint
readonly() keeps reactivity, so changes in state reflect in readOnlyState
Concept Snapshot
readonly() wraps reactive data to prevent changes.
It blocks mutations but keeps data reactive.
Use readonly() to share immutable state safely.
Mutation attempts warn and do not change data.
Reading readonly data works normally.
Full Transcript
In Vue, readonly() creates an immutable reactive proxy around reactive data. This means you can read the data and it updates reactively, but any attempt to change it is blocked and warned. The flow starts by creating reactive data, then wrapping it with readonly(). When you try to modify the readonly data, Vue stops the change and keeps the original value. This helps share data safely without accidental changes. The execution table shows each step: creating reactive state, wrapping it readonly, trying to mutate (blocked), and reading the value. The variable tracker shows state and readonly proxy values over time. Key moments clarify why mutation is blocked and that readonly data remains reactive. The quiz tests understanding of value changes and mutation blocking. Overall, readonly() is a simple way to protect reactive data from unwanted changes while keeping reactivity intact.

Practice

(1/5)
1. What does the readonly function do in Vue's reactivity system?
easy
A. It creates an immutable reactive object that cannot be changed directly.
B. It makes a reactive object completely non-reactive and static.
C. It clones the reactive object and allows changes only on the clone.
D. It converts a reactive object into a plain JavaScript object.

Solution

  1. Step 1: Understand the purpose of readonly

    The readonly function wraps a reactive object to prevent direct modifications, making it immutable.
  2. Step 2: Compare with other behaviors

    Unlike cloning or removing reactivity, readonly keeps the object reactive but disallows changes.
  3. Final Answer:

    It creates an immutable reactive object that cannot be changed directly. -> Option A
  4. Quick Check:

    Readonly = Immutable reactive object [OK]
Hint: Readonly means no direct changes allowed on reactive data [OK]
Common Mistakes:
  • Thinking readonly removes reactivity completely
  • Assuming readonly clones data instead of wrapping
  • Believing readonly allows changes on the wrapped object
2. Which of the following is the correct way to create a readonly reactive object in Vue?
easy
A. const data = readonly({ count: 0 })
B. const data = readonly(reactive({ count: 0 }))
C. const data = reactive(readonly({ count: 0 }))
D. const data = reactive({ count: 0 }).readonly()

Solution

  1. Step 1: Understand the correct usage order

    You first create a reactive object, then wrap it with readonly to make it immutable.
  2. Step 2: Evaluate each option

    const data = readonly(reactive({ count: 0 })) correctly wraps a reactive object with readonly. const data = reactive(readonly({ count: 0 })) tries to make a readonly object reactive, which is invalid. const data = readonly({ count: 0 }) skips reactive, so no reactivity. const data = reactive({ count: 0 }).readonly() uses a non-existent method.
  3. Final Answer:

    const data = readonly(reactive({ count: 0 })) -> Option B
  4. Quick Check:

    Wrap reactive with readonly = const data = readonly(reactive({ count: 0 })) [OK]
Hint: Wrap reactive() inside readonly() to make immutable reactive [OK]
Common Mistakes:
  • Calling readonly before reactive
  • Skipping reactive and only using readonly
  • Using non-existent readonly method on reactive
3. Given the code below, what will be logged to the console?
const state = reactive({ count: 1 });
const readOnlyState = readonly(state);

readOnlyState.count = 5;
console.log(readOnlyState.count);
state.count = 10;
console.log(readOnlyState.count);
medium
A. Error on assignment, then 10
B. 5 and 10
C. 1 and 1
D. 1 and 10

Solution

  1. Step 1: Understand readonly behavior on assignment

    Assigning to readOnlyState.count causes a warning in development mode, but the change is ignored and value remains 1.
  2. Step 2: Check reactive source update reflection

    First console.log(readOnlyState.count) outputs 1. Changing state.count to 10 updates the source, so second log is 10.
  3. Final Answer:

    1 and 10 -> Option D
  4. Quick Check:

    Readonly warns/ignores direct change, reflects source updates [OK]
Hint: Readonly blocks direct changes but shows source updates [OK]
Common Mistakes:
  • Expecting readonly to allow direct assignment
  • Thinking readonly copies data instead of reflecting source
  • Ignoring error/warning on assignment to readonly
4. Identify the error in the following Vue code using readonly:
import { reactive, readonly } from 'vue';
const data = readonly({ count: 0 });
data.count = 1;
console.log(data.count);
medium
A. You cannot assign to a readonly object directly.
B. You must use ref() instead of reactive() for readonly.
C. Readonly does not exist in Vue's API.
D. You must wrap a reactive object with readonly, not a plain object.

Solution

  1. Step 1: Check how readonly is used

    The code creates a readonly proxy but then attempts data.count = 1.
  2. Step 2: Understand readonly requirements

    Readonly prevents direct mutations, causing a development warning and ignoring the assignment.
  3. Final Answer:

    You cannot assign to a readonly object directly. -> Option A
  4. Quick Check:

    Cannot mutate readonly objects [OK]
Hint: Readonly objects cannot be mutated directly [OK]
Common Mistakes:
  • Attempting to mutate readonly objects directly
  • Assuming readonly works without reactive
  • Confusing readonly with ref
5. You have a reactive object state shared across components. You want to expose it as readonly to prevent accidental changes but still reflect updates. Which approach correctly achieves this and why?
const state = reactive({ user: { name: 'Alice' }, count: 0 });

// Options:
// A) const safeState = readonly(state);
// B) const safeState = reactive(state);
// C) const safeState = readonly({ ...state });
// D) const safeState = reactive(readonly(state));
hard
A. Create a shallow copy and make it readonly, but it won't reflect nested updates.
B. Wrap the reactive state with readonly to prevent direct changes but reflect updates.
C. Wrap the state again with reactive, which allows changes and duplicates reactivity.
D. Wrap readonly with reactive, which is invalid and causes errors.

Solution

  1. Step 1: Analyze each option's effect

    Wrap the reactive state with readonly to prevent direct changes but reflect updates. correctly wraps the reactive object with readonly, making it immutable but still reactive to source changes. Wrap the state again with reactive, which allows changes and duplicates reactivity. duplicates reactivity and allows changes. Create a shallow copy and make it readonly, but it won't reflect nested updates. creates a shallow copy, losing nested reactivity. Wrap readonly with reactive, which is invalid and causes errors. is invalid usage.
  2. Step 2: Confirm correct approach for safe sharing

    Readonly wrapping reactive is the recommended way to share data safely without allowing modifications but reflecting updates.
  3. Final Answer:

    Wrap the reactive state with readonly to prevent direct changes but reflect updates. -> Option C
  4. Quick Check:

    Readonly wraps reactive for safe, immutable sharing [OK]
Hint: Wrap reactive with readonly to share immutable reactive data [OK]
Common Mistakes:
  • Using shallow copies losing nested reactivity
  • Wrapping readonly inside reactive incorrectly
  • Duplicating reactivity causing unexpected mutations
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