--- title: Single-File Component Structure, Styling, and Template Patterns impact: MEDIUM impactDescription: Consistent SFC structure and styling choices improve maintainability, tooling support, and render performance type: best-practice tags: [vue3, sfc, scoped-css, styles, build-tools, performance, template, v-html, v-for, computed, v-if, v-show] --- # Single-File Component Structure, Styling, and Template Patterns **Impact: MEDIUM** - Using SFCs with consistent structure and performant styling keeps components easier to maintain and avoids unnecessary render overhead. ## Task List - Use `.vue` SFCs instead of separate `.js`/`.ts` and `.css` files for components - Colocate template, script, and styles in the same SFC by default - Use PascalCase for component names in templates and filenames - Prefer component-scoped styles - Prefer class selectors (not element selectors) in scoped CSS for performance - Access DOM / component refs with `useTemplateRef()` in Vue 3.5+ - Use camelCase keys in `:style` bindings for consistency and IDE support - Use `v-for` and `v-if` correctly - Never use `v-html` with untrusted/user-provided content - Choose `v-if` vs `v-show` based on toggle frequency and initial render cost ## Colocate template, script, and styles **BAD:** ``` components/ ├── UserCard.vue ├── UserCard.js └── UserCard.css ``` **GOOD:** ```vue ``` ## Use PascalCase for component names **BAD:** ```vue ``` **GOOD:** ```vue ``` ## Best practices for ` ``` **GOOD:** ```vue ``` **GOOD:** ```css /* src/assets/main.css */ /* ✅ resets, tokens, typography, app-wide rules */ :root { --radius: 999px; } ``` ### Use class selectors in scoped CSS **BAD:** ```vue ``` **GOOD:** ```vue ``` ## Access DOM / component refs with `useTemplateRef()` For Vue 3.5+: use `useTemplateRef()` to access template refs. ```vue ``` ## Use camelCase in `:style` bindings **BAD:** ```vue ``` **GOOD:** ```vue ``` ## Use `v-for` and `v-if` correctly ### Always provide a stable `:key` - Prefer primitive keys (`string | number`). - Avoid using objects as keys. **GOOD:** ```vue
  • ``` ### Avoid `v-if` and `v-for` on the same element It leads to unclear intent and unnecessary work. ([Reference](https://vuejs.org/guide/essentials/list.html#v-for-with-v-if)) **To filter items** **BAD:** ```vue
  • {{ user.name }}
  • ``` **GOOD:** ```vue ``` **To conditionally show/hide the entire list** **GOOD:** ```vue ``` ## Never render untrusted HTML with `v-html` **BAD:** ```vue ``` **GOOD:** ```vue ``` ## Choose `v-if` vs `v-show` by toggle behavior **BAD:** ```vue ``` **GOOD:** ```vue ```