SFC Syntax Specification
Overview
A Vue Single-File Component (SFC), conventionally using the *.vue
file extension, is a custom file format that uses an HTML-like syntax to describe a Vue component. A Vue SFC is syntactically compatible with HTML.
Each *.vue
file consists of three types of top-level language blocks: <template>
, <script>
, and <style>
, and optionally additional custom blocks:
vue
<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>
Language Blocks
<template>
Each
*.vue
file can contain at most one top-level<template>
block.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 (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 (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:
Handling of Custom Blocks will depend on tooling - if you want to build your own custom block integrations, see the SFC custom block integrations tooling section 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 explicitly 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:
template
<script lang="ts">
// use TypeScript
</script>
lang
can be applied to any block - for example we can use <style>
with Sass and <template>
with Pug:
template
<template lang="pug">
p {{ msg }}
</template>
<style lang="scss">
$primary-color: #333;
body {
color: $primary-color;
}
</style>
Note that integration with various pre-processors may differ by toolchain. Check out the respective documentation 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:
vue
<template src="./template.html"></template>
<style src="./style.css"></style>
<script src="./script.js"></script>
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:
vue
<!-- import a file from the installed "todomvc-app-css" npm package -->
<style src="todomvc-app-css/index.css" />
src
imports also work with custom blocks, e.g.:
vue
<unit-test src="./unit-test.js">
</unit-test>
Note
While using aliases in src
, don't start with ~
, anything after it is interpreted as a module request. This means you can reference assets inside node modules:
vue
<img src="~some-npm-package/foo.png">
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 -->