DEV Community

Mikihiro Saito
Mikihiro Saito

Posted on

Vue Templates: Should They Start from the Top or the Bottom?

This article is translated with Chat GPT from my article in Zenn

https://zenn.dev/mikinovation/articles/20221008-template-upper-lower

Introduction

Vue is a UI framework that recommends writing components as Single File Components (SFCs), combining HTML, CSS, and JavaScript in one file.

A question arises: "Some people and projects write SFCs differently, especially the order of template, script and style tags."

Let's dive into specifics. Below is a code snippet from the official Vue 3 documentation:

<script setup>
import { ref, onMounted } from 'vue'

// reactive state
const count = ref(0)

// functions that mutate state and trigger updates
function increment() {
  count.value++
}

// lifecycle hooks
onMounted(() => {
  console.log(`The initial count is ${count.value}.`)
})
</script>

<template>
  <button @click="increment">Count is: {{ count }}</button>
</template>

<style scoped>
button {
  font-weight: bold;
}
</style>
Enter fullscreen mode Exit fullscreen mode

However, being familiar with Vue 2, I've been writing Vue 3 in the following way:

<template>
  <button @click="increment">Count is: {{ count }}</button>
</template>

<script setup>
import { ref, onMounted } from 'vue'

// reactive state
const count = ref(0)

// functions that mutate state and trigger updates
function increment() {
  count.value++
}

// lifecycle hooks
onMounted(() => {
  console.log(`The initial count is ${count.value}.`)
})
</script>

<style scoped>
button {
  font-weight: bold;
}
</style>
Enter fullscreen mode Exit fullscreen mode

Notice the reverse order of template and script tags.

Conclusion:

In SFCs, I recommend writing in the order of script tag→template tag→style tag.

Benefits of Writing the Script Tag First:

When writing in the order of script→template→style, you get these advantages:

Separation of Concerns Between Component Logic and Design

In projects, cooperation with designers is often necessary. Even if one person handles both front-end logic and design, it's typical to separate tasks based on interest in logic versus design.

When focusing on logic, attention centers on script and template tags. When focusing on design, attention shifts to template and style tags.

What if we wrote in the order of template→script→style? Those with a higher interest in design might find this troublesome.

Let's revisit the earlier example:

<template>
  <button @click="increment">Count is: {{ count }}</button>
</template>

<script setup>
import { ref, onMounted } from 'vue'

// reactive state
const count = ref(0)

// functions that mutate state and trigger updates
function increment() {
  count.value++
}

// lifecycle hooks
onMounted(() => {
  console.log(`The initial count is ${count.value}.`)
})
</script>

<style scoped>
button {
  font-weight: bold;
}
</style>
Enter fullscreen mode Exit fullscreen mode

Interest in design concentrates on template and style tags. However, having the script tag in between can be a slight disadvantage.

Sure, the Composition API allows for separating logic from components, but when defining lifecycle hooks, props, emits, etc., it's preferable not to intersperse unrelated areas.

An exception is when defining inline styles like Tailwind CSS. In such cases, the order of script and template tags doesn't matter as design focuses solely on the template.

At least when defining CSS in style tags, it's more productive to write the template tag after the script tag.

Affinity with Other Frameworks:

Considering compatibility with other frameworks, I again recommend the order of script→template→style tags. Take React, for instance, where you can write as follows (using CSS Modules for styling):

import React from 'react'
import styles from './styles.module.css'

export const Button = () => {
  const [count, setCount] = useState(0)

  const increment = () => {
    setCount(count + 1)
  }

  return (
    <button className={styles.btn} onClick={increment}>
      Count is: {count}
    </button>
  )
}
Enter fullscreen mode Exit fullscreen mode

In JSX, there's no template tag; the view is returned as the function's output, naturally leading to a logic→View sequence. This applies to libraries and frameworks using JSX, like Solid.js.

What about Svelte? While simpler in syntax than Vue, its writing style is relatively similar. In Svelte, everything except script and style tags is treated as a template, as seen in most sample codes.

As for Angular, since HTML, CSS, and Script are in separate files, it's not a direct reference in this context.

Most popular frameworks tend to write in the order of logic→View, so for Vue, writing in the order of script→template→style tags makes a sence.

Summary:

In this article, we explored the tag order in Vue's SFCs. To reiterate, I recommend writing in the order of script→template→style tags in Vue. Of course, this is my personal opinion, and each project team should decide the best order for themselves.

Top comments (2)

Collapse
 
aloisseckar profile image
Alois Sečkár

Your arguments sound logical, but I still like template -> script -> style more and I think I'll stick to it. I find more natural first to see what is displayed than how it works. Also I have a lot of components with little to no logic, so having tiny <script> section sitting atop much bigger <template> also seems weird to me.

Collapse
 
orenmizr profile image
Oren Mizrahi

its template -> script -> style
first build the mockups. then break it to components. then add behaviors. it is the most organic in my opinion.