# Однофайловые компоненты

# Введение

Однофайловые компоненты Vue (они же файлы *.vue, или называемые сокращённо SFC, от Single File Component) — специальный формат файлов, позволяющий собрать в одном файле шаблон, логику и стилизацию компонента Vue. Пример однофайлового компонента:

<template>
  <p class="greeting">{{ greeting }}</p>
</template>

<script>
export default {
  data() {
    return {
      greeting: 'Привет всем!'
    }
  }
}
</script>

<style>
.greeting {
  color: red;
  font-weight: bold;
}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

Как можно увидеть, однофайловые компоненты Vue естественно развивают использование классического трио: HTML, CSS и JavaScript. Чаще всего *.vue файл состоит из трёх секций языковых блоков: <template>, <script> и <style>:

  • Секция <script> представляет собой обычный модуль JavaScript. Модуль в качестве экспорта по умолчанию должен возвращать объект с определением компонента Vue.
  • Секция <template> определяет шаблон компонента.
  • Секция <style> определяет CSS, связанный с компонентом.

Более подробную информацию можно найти в разделе спецификации синтаксиса SFC.

# Как они работают

Однофайловые компоненты Vue — формат, специфический для фреймворка, который нужно предварительно скомпилировать в обычный JavaScript и CSS с помощью @vue/compiler-sfc (opens new window). Скомпилированный однофайловый компонент это обычный ES-модуль JavaScript — а значит, при правильной настройке сборки, импортировать однофайловые компоненты можно как обычные модули:

<script>
import MyComponent from './MyComponent.vue'

export default {
  components: {
    MyComponent
  }
}
</script>
1
2
3
4
5
6
7
8
9

Секции <style> однофайловых компонентов во время разработки будут внедряться как нативные теги <style> для поддержки горячих обновлений. При сборке в production они могут быть извлечены и объединены в одном CSS-файле.

Попробовать использовать однофайловые компоненты и разобраться как они компилируются можно в песочнице Vue SFC (opens new window).

В реальных проектах компилятор однофайловых компонентов интегрируется с системой сборки, такой как Vite (opens new window) или Vue CLI (opens new window) (которая использует под капотом webpack (opens new window)), а Vue предоставляет официальные инструменты для развёртывания, чтобы как можно быстрее начать работу с однофайловыми компонентами. Более подробную информацию можно найти в разделе инструментария SFC.

# Почему SFC

Несмотря на то, что однофайловые компоненты требуют этапа сборки, взамен они предоставляют множество преимуществ:

Однофайловые компоненты — определяющая особенность Vue как фреймворка и рекомендуемый подход для использования Vue в следующих сценариях:

  • Одностраничные приложения (Single-Page Applications, SPA)
  • Генерация статических сайтов (Static Site Generation, SSG)
  • Любые нетривиальные фронтенды, где этап сборки может быть оправдан для улучшения опыта разработки (DX).

Понимаем, что тем не менее могут быть сценарии, в которых однофайловые компоненты могут показаться излишеством. Именно поэтому Vue по-прежнему можно использовать в обычном JavaScript и без этапа сборки. Если требуется просто улучшить статичный HTML лёгкими взаимодействиями, то обратите также внимание на petite-vue (opens new window), подмножество Vue, размером 5 КБайт, оптимизированное для прогрессивного улучшения.

# Что насчёт разделения ответственности?

Некоторым пользователям, с традиционным образованием в области веб-разработки, может показаться, что однофайловые компоненты смешивают различные аспекты в одном месте — когда предполагается, что HTML/CSS/JS должны их разделять!

Для ответа на этот вопрос важно согласиться с идеей, что разделение ответственности это не то же самое, что разделение на файлы по типу. Конечной целью инженерных принципов является улучшение поддержки кодовой базы. Разделение ответственности, применяемое догматически, как разделение по типу файлов, не помогает достичь этой цели в контексте всё более сложных фронтенд-приложений.

В современной разработке UI обычно вместо разделения кодовой базы на три огромных слоя, что тесно переплетаются друг с другом, имеет больше смысла разделять их на слабо связанные компоненты и компоновать уже их. Внутри компонента, его шаблон, логика и стили неразрывно связаны между собой, что позволяет сделать компонент более цельным и удобным в поддержке.

Если идея однофайловых компонентов не по душе — можно разнести на отдельные файлы JavaScript и CSS и пользоваться возможностями горячей перезагрузки модулей и предварительной компиляцией с помощью импортов через src.