--- title: Template Ref Unwrapping Only Works for Top-Level Properties impact: MEDIUM impactDescription: Nested refs in template expressions render as [object Object] instead of their values type: capability tags: [vue3, reactivity, ref, template, unwrapping] --- # Template Ref Unwrapping Only Works for Top-Level Properties **Impact: MEDIUM** - Vue only auto-unwraps refs that are top-level properties in the template render context. Nested refs (refs inside objects) are NOT unwrapped in expressions, causing `[object Object]` rendering or calculation errors. This caveat trips up developers when they store refs inside reactive objects or plain objects and try to use them in template expressions like `{{ object.count + 1 }}`. ## Task Checklist - [ ] Keep refs at the top level of your setup return or script setup - [ ] Destructure nested refs to top-level variables before using in expressions - [ ] Be aware that text interpolation `{{ object.ref }}` DOES unwrap, but expressions `{{ object.ref + 1 }}` do NOT - [ ] Consider restructuring data to avoid nested refs in templates **Incorrect:** ```vue ``` **Correct:** ```vue ``` ```vue ``` ```vue ``` ```javascript // WHY this happens: // - Template compilation only adds .value to top-level identifiers // - {{ count + 1 }} compiles to: count.value + 1 // - {{ object.id + 1 }} compiles to: object.id + 1 (no .value added!) // - Plain {{ object.id }} has special handling for display purposes ``` ## Reference - [Vue.js Reactivity Fundamentals - Caveat when Unwrapping in Templates](https://vuejs.org/guide/essentials/reactivity-fundamentals.html#caveat-when-unwrapping-in-templates)