Since Vue 3 the common way to order Single File Components is <script>
, <template>
, <style>
instead of <template>
, <script>
, <style>
which was common before. The
For me, this feels alien. I am a visual thinker and if you see the developer as a user as well, the idea of displaying what a component looks like first is only natural. The user does not need to know how it works and if they want to, they can inspect the corresponding logic by i.e. clicking on it in the template.
The Template Order Tradeoff
The template-first approach prioritizes human comprehension over technical dependency order, reflecting a user-centered design philosophy. However, placing templates second allows logic and style to exist as siblings to the template, which maintains technical correctness at the cost of less intuitive readability.
Visual Processing Advantage
Visual thinking provides
to comprehension. HTML is still text-based but compared to JavaScript . This should result in templates with minimal logic to be the easiest component to understand in web development.Interactive Logic Exploration
Most IDEs allow for interactive elements to be clicked on for logical components to reveal their JavaScript implementation, thus creating a natural progression from visual structure to functional behavior. This pattern resembles modern component inspection tools that let developers explore code hierarchically in a top-down way. As in a Personal Knowledge Management system, creation should be preferred to be bottom-up but exploring top-down.
Style and Script Placement
CSS styling is often secondary to structure (and optional too) and can logically be placed at the bottom of component files. Since JavaScript is optional as well, placing the HTML template first creates a more semantically meaningful organization.
While technical correctness would suggest an order of imports → JavaScript → HTML -> CSS (as dependencies should precede their usage), this contradicts the semantic importance of the template itself.
Tailwind
Bonus: Tailwind and similar CSS tools gain popularity and are based on inline styling. This makes the CSS block even more obsolete.
Code Examples
<template>
<!-- Immediately see what the component renders and does -->
<!-- Visual comprehension first - you understand the purpose at a glance -->
<div class="counter">
<h2>{{ count }}</h2>
<!-- Interactive elements reveal their purpose visually -->
<button @click="increment">+1</button>
</div>
</template>
<script setup>
// Logic follows visual structure - you already know what this supports
// In Nuxt this is also omitted
import { ref } from 'vue';
// After seeing the template, these variables make immediate sense
const count = ref(0);
const increment = () => count.value++;
// Understanding the implementation is easier after seeing its purpose
</script>
<style scoped>
/* Styling comes last as it's enhancement, not core functionality */
.counter {
padding: 10px;
border: 1px solid #ccc;
}
</style>
<script setup>
// Dependencies and logic defined before use - technically correct order
// In Nuxt this is also omitted
import { ref } from 'vue';
// Variables defined before they appear in template
const count = ref(0);
const increment = () => count.value++;
</script>
<template>
<!-- Template appears after its dependencies are defined -->
<!-- Must read through logic before seeing what component does -->
<div class="counter">
<h2>{{ count }}</h2>
<button @click="increment">+1</button>
</div>
</template>
<style scoped>
/* Styling at the end is now closer to the template */
.counter {
padding: 10px;
border: 1px solid #ccc;
}
</style>