Readonly makes reactive data unchangeable. It helps keep data safe from accidental changes.
Readonly for immutable reactive data in Vue
import { reactive, readonly } from 'vue'; const original = reactive({ count: 0 }); const locked = readonly(original);
readonly() wraps reactive data to make it immutable.
Trying to change locked will not update the data and will warn in dev mode.
import { reactive, readonly } from 'vue'; const state = reactive({ name: 'Alice' }); const frozenState = readonly(state); // frozenState.name = 'Bob'; // This will not change the value
import { readonly } from 'vue'; const config = readonly({ theme: 'dark', language: 'en' }); // config.theme = 'light'; // This change is ignored
This Vue component shows a count that is wrapped in readonly. The button tries to increment the count by changing the original reactive state. Direct changes to the readonly object are ignored.
<template>
<div>
<p>Count: {{ locked.count }}</p>
<button @click="increment">Increment</button>
</div>
</template>
<script setup>
import { reactive, readonly } from 'vue';
const state = reactive({ count: 0 });
const locked = readonly(state);
function increment() {
// Trying to change locked.count will not work
// locked.count++ // This will warn and not update
// Change original reactive state instead
state.count++;
}
</script>Readonly only prevents changes on the wrapped object, not on the original reactive source.
Readonly is useful to protect data passed to child components.
In development mode, Vue warns if you try to mutate readonly data.
Readonly makes reactive data immutable to prevent accidental changes.
Use it when you want to share data safely without allowing modifications.
Readonly objects reflect changes from the original reactive source but cannot be changed directly.
Practice
readonly function do in Vue's reactivity system?Solution
Step 1: Understand the purpose of
Thereadonlyreadonlyfunction wraps a reactive object to prevent direct modifications, making it immutable.Step 2: Compare with other behaviors
Unlike cloning or removing reactivity,readonlykeeps the object reactive but disallows changes.Final Answer:
It creates an immutable reactive object that cannot be changed directly. -> Option AQuick Check:
Readonly = Immutable reactive object [OK]
- Thinking readonly removes reactivity completely
- Assuming readonly clones data instead of wrapping
- Believing readonly allows changes on the wrapped object
Solution
Step 1: Understand the correct usage order
You first create a reactive object, then wrap it withreadonlyto make it immutable.Step 2: Evaluate each option
const data = readonly(reactive({ count: 0 })) correctly wraps a reactive object withreadonly. 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.Final Answer:
const data = readonly(reactive({ count: 0 })) -> Option BQuick Check:
Wrap reactive with readonly = const data = readonly(reactive({ count: 0 })) [OK]
- Calling readonly before reactive
- Skipping reactive and only using readonly
- Using non-existent readonly method on reactive
const state = reactive({ count: 1 });
const readOnlyState = readonly(state);
readOnlyState.count = 5;
console.log(readOnlyState.count);
state.count = 10;
console.log(readOnlyState.count);Solution
Step 1: Understand readonly behavior on assignment
Assigning toreadOnlyState.countcauses a warning in development mode, but the change is ignored and value remains 1.Step 2: Check reactive source update reflection
Firstconsole.log(readOnlyState.count)outputs 1. Changingstate.countto 10 updates the source, so second log is 10.Final Answer:
1 and 10 -> Option DQuick Check:
Readonly warns/ignores direct change, reflects source updates [OK]
- Expecting readonly to allow direct assignment
- Thinking readonly copies data instead of reflecting source
- Ignoring error/warning on assignment to readonly
import { reactive, readonly } from 'vue';
const data = readonly({ count: 0 });
data.count = 1;
console.log(data.count);Solution
Step 1: Check how readonly is used
The code creates a readonly proxy but then attemptsdata.count = 1.Step 2: Understand readonly requirements
Readonly prevents direct mutations, causing a development warning and ignoring the assignment.Final Answer:
You cannot assign to a readonly object directly. -> Option AQuick Check:
Cannot mutate readonly objects [OK]
- Attempting to mutate readonly objects directly
- Assuming readonly works without reactive
- Confusing readonly with ref
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));Solution
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.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.Final Answer:
Wrap the reactive state with readonly to prevent direct changes but reflect updates. -> Option CQuick Check:
Readonly wraps reactive for safe, immutable sharing [OK]
- Using shallow copies losing nested reactivity
- Wrapping readonly inside reactive incorrectly
- Duplicating reactivity causing unexpected mutations
Ready to prove it?
Pass the test and this pattern moves unknown
