Shallow ref and shallow reactive help you track changes only on the top level of an object or array. This makes your app faster when you don't need to watch deep changes.
Shallow ref and shallow reactive in Vue
import { shallowRef, shallowReactive } from 'vue'; const myShallowRef = shallowRef(initialValue); const myShallowReactive = shallowReactive(initialObject);
shallowRef tracks changes only when the reference itself changes, not inside the object.
shallowReactive makes the top-level properties reactive but does not make nested objects reactive.
shallowRef holding an object. Changing properties inside user.value won't trigger updates, but replacing user.value with a new object will.import { shallowRef } from 'vue'; const user = shallowRef({ name: 'Anna', age: 25 }); // Changing user.value to a new object triggers updates user.value = { name: 'Ben', age: 30 };
settings.theme change is reactive, but changing options.fontSize inside the nested object is not reactive.import { shallowReactive } from 'vue'; const settings = shallowReactive({ theme: 'dark', options: { fontSize: 14 } }); settings.theme = 'light'; // reactive settings.options.fontSize = 16; // NOT reactive
This Vue app shows how shallowRef and shallowReactive behave. Only changes to the top-level object or properties trigger the watchers and console logs.
import { createApp, shallowRef, shallowReactive, watch } from 'vue'; const App = { setup() { const shallowUser = shallowRef({ name: 'Anna', age: 25 }); const shallowSettings = shallowReactive({ theme: 'dark', options: { fontSize: 14 } }); watch(() => shallowUser.value, () => { console.log('shallowUser changed'); }); watch(() => shallowSettings.theme, () => { console.log('Theme changed'); }); watch(() => shallowSettings.options.fontSize, () => { console.log('Font size changed'); }); // Change nested property inside shallowRef (no trigger) shallowUser.value.name = 'Ben'; // Replace shallowRef value (triggers) shallowUser.value = { name: 'Cara', age: 28 }; // Change top-level shallowReactive property (triggers) shallowSettings.theme = 'light'; // Change nested shallowReactive property (no trigger) shallowSettings.options.fontSize = 16; return {}; }, template: `<div>Check console for watch logs.</div>` }; createApp(App).mount('#app');
Use shallowRef when you want to track changes only when the whole object changes, not its inner parts.
Use shallowReactive when you want reactivity on top-level properties but want to ignore nested objects for performance.
Remember that nested changes inside shallow reactive objects or shallow refs do not trigger updates.
Shallow ref tracks changes only when the reference changes, not inside the object.
Shallow reactive tracks changes on top-level properties only, ignoring nested objects.
Use them to improve performance when deep reactivity is not needed.