# Vue 单文件组件 (SFC) 规范

# 简介

一个 *.vue 文件是一个自定义文件格式,它使用类似 HTML 的语法来描述一个 Vue 组件。每个 *.vue 文件包含三种类型的顶级语言块:<template><script><style>,以及可选的额外自定义块。

<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 将解析该文件,提取每个语言块,如果需要,将它们通过其他加载器,最后将它们重新组装成一个 ES 模块,其默认导出是一个 Vue.js 组件选项对象。

vue-loader 支持使用非默认语言,例如 CSS 预处理器和编译到 HTML 的模板语言,方法是为语言块指定 lang 属性。例如,您可以像这样使用 Sass 为您的组件的样式:

<style lang="sass">
  /* write Sass! */
</style>

更多详细信息可以在 使用预处理器 中找到。

# 语言块

# 模板

  • 每个 *.vue 文件一次最多可以包含一个 <template> 块。

  • 内容将被提取并传递给 vue-template-compiler 并预编译成 JavaScript 渲染函数,最后注入到 <script> 部分中导出的组件中。

# 脚本

  • 每个 *.vue 文件一次最多可以包含一个 <script> 块。

  • 脚本作为 ES 模块执行。

  • 默认导出应该是一个 Vue.js 组件选项对象。导出由 Vue.extend() 创建的扩展构造函数也受支持,但首选普通对象。

  • 任何与 .js 文件(或由 lang 属性指定的扩展名)匹配的 webpack 规则也将应用于 <script> 块中的内容。

# 样式

  • 默认匹配:/\.css$/

  • 单个 *.vue 文件可以包含多个 <style> 标签。

  • <style> 标签可以具有 scopedmodule 属性(参见 作用域 CSSCSS 模块)以帮助将样式封装到当前组件中。多个具有不同封装模式的 <style> 标签可以混合在同一个组件中。

  • 任何与 .css 文件(或由 lang 属性指定的扩展名)匹配的 webpack 规则也将应用于 <style> 块中的内容。

# 自定义块

可以在 *.vue 文件中包含其他自定义块以满足任何项目特定需求,例如 <docs> 块。vue-loader 将使用标签名称来查找应应用于该部分内容的 webpack 加载器。webpack 加载器应在 vue-loader 选项的 loaders 部分中指定。

有关更多详细信息,请参见 自定义块

# Src 导入

如果您更喜欢将 *.vue 组件拆分成多个文件,您可以使用 src 属性为语言块导入外部文件

<template src="./template.html"></template>
<style src="./style.css"></style>
<script src="./script.js"></script>

请注意,src 导入遵循与 webpack 模块请求相同的路径解析规则,这意味着

  • 相对路径需要以 ./ 开头
  • 您可以从 npm 依赖项导入资源
<!-- import a file from the installed "todomvc-app-css" npm package -->
<style src="todomvc-app-css/index.css">

src 导入也适用于自定义块,例如:

<unit-test src="./unit-test.js">
</unit-test>

# 语法高亮 / IDE 支持

目前,以下 IDE/编辑器支持语法高亮

非常欢迎为其他编辑器/IDE 做出贡献!如果您在 Vue 组件中没有使用任何预处理器,您也可以通过将 *.vue 文件在您的编辑器中视为 HTML 来获得不错的语法高亮。

# 注释

在每个块中,您应该使用所用语言的注释语法(HTML、CSS、JavaScript、Jade 等)。对于顶级注释,请使用 HTML 注释语法:<!-- 这里写注释内容 -->