Performance: Composable with reactive state
This affects how efficiently the UI updates when reactive state changes, impacting interaction responsiveness and rendering speed.
import { ref } from 'vue'; export function useCounter() { const count = ref(0); return { count }; }
import { reactive } from 'vue'; const state = reactive({ count: 0 }); export function useCounter() { return { state }; }
| Pattern | DOM Operations | Reflows | Paint Cost | Verdict |
|---|---|---|---|---|
| Shared reactive state in composable | Many components update DOM nodes | Multiple reflows triggered | High paint cost due to wide updates | [X] Bad |
| Instance-specific reactive state in composable | Only affected component updates DOM | Single reflow per update | Lower paint cost focused on small area | [OK] Good |
ref is used to create a reactive primitive like a number, string, or boolean. reactive is for objects.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.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);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);user object is created with reactive and its properties can be updated directly.updateName function updates user.name correctly and is returned for use.ref([]) so we access the array via tasks.value.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.Pass the test and this pattern moves unknown