Vue Component Spec
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>
vue-loader
will parse the file, extract each language block, pipe them through other loaders if necessary, and finally assemble them back into a CommonJS module whose module.exports
is a Vue.js component options object.
vue-loader
supports using non-default languages, such as CSS pre-processors and compile-to-HTML template languages, by specifying the lang
attribute for a language block. For example, you can use Sass for the style of your component like this:
<style lang="sass">
/* write Sass! */
</style>
More details can be found in Using Pre-Processors.
Language Blocks
<template>
Default language:
html
.Each
*.vue
file can contain at most one<template>
block at a time.Contents will be extracted as a string and used as the
template
option for the compiled Vue component.
<script>
Default language:
js
(ES2015 is supported automatically ifbabel-loader
orbuble-loader
is detected).Each
*.vue
file can contain at most one<script>
block at a time.The script is executed in a CommonJS like environment (just like a normal
.js
module bundled via webpack), which means you canrequire()
other dependencies. And with ES2015 support, you can also use theimport
andexport
syntax.The script must export a Vue.js component options object. Exporting an extended constructor created by
Vue.extend()
is also supported, but a plain object is preferred.
<style>
Default Language:
css
.Multiple
<style>
tags are supported in a single*.vue
file.A
<style>
tag can havescoped
ormodule
attributes (see Scoped CSS and CSS Modules) to help encapsulate the styles to the current component. Multiple<style>
tags with different encapsulation modes can be mixed in the same component.By default, contents will be extracted and dynamically inserted into the document's
<head>
as an actual<style>
tag usingstyle-loader
. It's also possible to configure webpack so that all styles in all components are extracted into a single CSS file.
Custom Blocks
Only supported in vue-loader 10.2.0+
Additional custom blocks can be included in a *.vue
file for any project specific needs, for example a <docs>
block. vue-loader
will use the tag name to look up which webpack loaders should be applied to the contents of the section. The webpack loaders should be specified in the loaders
section of vue-loader
options.
For mode details, see Custom Blocks.
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>
Beware that src
imports follow the same path resolution rules to CommonJS require()
calls, which means for relative paths you need to start with ./
, and you can import resources directly from installed NPM packages, e.g:
<!-- 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.:
<unit-test src="./unit-test.js">
</unit-test>
Syntax Highlighting
Currently there is syntax highlighting support for Sublime Text, Atom, Vim, Emacs, Visual Studio Code, Brackets, and JetBrains products (WebStorm, PhpStorm, etc). Contributions for other editors/IDEs are highly appreciated! If you are not using any pre-processors in Vue components, you can also get by treating *.vue
files as HTML in your editor.
Comments
Inside each block you shall use the comment syntax of the language being used (HTML, CSS, JavaScript, Jade, etc). For top-level comments, use HTML comment syntax: <!-- comment contents here -->