# SFC Syntax Specification
# Intro
A *.vue
file is a custom file format that uses HTML-like syntax to describe a Vue component. Each *.vue
file consists of three types of top-level language blocks: <template>
, <script>
, and <style>
, and optionally additional custom blocks:
<template>
<div class="example">{{ msg }}</div>
</template>
<script>
export default {
data() {
return {
msg: 'Hello world!'
}
}
}
</script>
<style>
.example {
color: red;
}
</style>
<custom1>
This could be e.g. documentation for the component.
</custom1>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# Language Blocks
# <template>
Each
*.vue
file can contain at most one top-level<template>
block at a time.Contents will be extracted and passed on to
@vue/compiler-dom
, pre-compiled into JavaScript render functions, and attached to the exported component as itsrender
option.
# <script>
Each
*.vue
file can contain at most one<script>
block at a time (excluding<script setup>
).The script is executed as an ES Module.
The default export should be a Vue component options object, either as a plain object or as the return value of defineComponent.
# <script setup>
Each
*.vue
file can contain at most one<script setup>
block at a time (excluding normal<script>
).The script is pre-processed and used as the component's
setup()
function, which means it will be executed for each instance of the component. Top-level bindings in<script setup>
are automatically exposed to the template. For more details, see dedicated documentation on<script setup>
.
# <style>
A single
*.vue
file can contain multiple<style>
tags.A
<style>
tag can havescoped
ormodule
attributes (see SFC Style Features for more details) to help encapsulate the styles to the current component. Multiple<style>
tags with different encapsulation modes can be mixed in the same component.
# Custom Blocks
Additional custom blocks can be included in a *.vue
file for any project-specific needs, for example a <docs>
block. Some real-world examples of custom blocks include:
- Gridsome:
<page-query>
(opens new window) - vite-plugin-vue-gql:
<gql>
(opens new window) - vue-i18n:
<i18n>
(opens new window)
Handling of Custom Blocks will depend on tooling - if you want to build your own custom block integrations, see SFC Tooling for more details.
# Automatic name
Inference
An SFC automatically infers the component's name from its filename in the following cases:
- Dev warning formatting
- DevTools inspection
- Recursive self-reference. E.g. a file named
FooBar.vue
can refer to itself as<FooBar/>
in its template. This has lower priority than explicity registered/imported components.
# Pre-Processors
Blocks can declare pre-processor languages using the lang
attribute. The most common case is using TypeScript for the <script>
block:
<script lang="ts">
// use TypeScript
</script>
2
3
lang
can be applied to any block - for example we can use <style>
with SASS (opens new window) and <template>
with Pug (opens new window):
<template lang="pug">
p {{ msg }}
</template>
<style lang="scss">
$primary-color: #333;
body {
color: $primary-color;
}
</style>
2
3
4
5
6
7
8
9
10
Note the intergration with pre-processors may differ based on the toolchain. Check out the respective documentations for examples:
# Src Imports
If you prefer splitting up your *.vue
components into multiple files, you can use the src
attribute to import an external file for a language block:
<template src="./template.html"></template>
<style src="./style.css"></style>
<script src="./script.js"></script>
2
3
Beware that src
imports follow the same path resolution rules as webpack module requests, which means:
- Relative paths need to start with
./
- You can import resources from npm dependencies:
<!-- import a file from the installed "todomvc-app-css" npm package -->
<style src="todomvc-app-css/index.css">
2
src
imports also work with custom blocks, e.g.:
<unit-test src="./unit-test.js">
</unit-test>
2
# Comments
Inside each block you shall use the comment syntax of the language being used (HTML, CSS, JavaScript, Pug, etc.). For top-level comments, use HTML comment syntax: <!-- comment contents here -->