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
*.vuefile 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 itsrenderoption.
<script>
Each
*.vuefile 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
*.vuefile 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
*.vuefile can contain multiple<style>tags.A
<style>tag can havescopedormoduleattributes (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.vuecan 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 -->