Гидратация клиентской части

Гидратация относится к процессу на стороне клиента, в течение которого Vue берёт статический HTML, отправленный сервером, и превращает его в динамический DOM, который может реагировать на изменения данных на стороне клиента.

В файле entry-client.js, мы просто монтируем приложение такой строкой:

// подразумеваем что шаблон в App.vue имеет корневой элемент с id="app"
app.$mount('#app')

Поскольку сервер уже отобразил разметку, мы, очевидно, не хотели бы её выбрасывать и заново создавать все элементы DOM. Вместо этого мы хотим «гидрировать» статическую разметку и сделать её интерактивной.

Если вы исследовали вывод после серверного рендеринга, вы могли заметить, что у корневого элемента приложения должен быть добавлен специальный атрибут:

<div id="app" data-server-rendered="true">

Специальный атрибут data-server-rendered позволяет клиентской части Vue знать, что разметка отображается сервером, и он должен монтироваться в режиме гидратации. Обратите внимание, что он не добавляет id="app", а только атрибут data-server-rendered: вам необходимо добавить ID или какой-либо другой селектор в корневой элемент самостоятельно или приложение не будет гидратироваться правильно.

Обратите внимание, что на элементах без атрибута data-server-rendered гидратация может быть принудительно выполнена при передаче true в аргументе hydrating метода $mount:

// Принудительная гидратация приложения
app.$mount('#app', true)

В режиме разработки Vue будет проверять, что виртуальное дерево DOM, сгенерированное на стороне клиента, совпадает с структурой DOM созданной на сервере. При нахождении несоответствия, он будет считать гидратацию неудачной, отказываться от существующего DOM и рендерить всё с нуля. В режиме production, эта проверка отключена для достижения максимальной производительности.

Предостережения при гидратации

Одна вещь, о которой нужно знать при использовании серверного рендеринга + гидратации на клиенте — некоторые специальные структуры HTML, которые могут быть изменены браузером. Например, когда вы пишете подобное в шаблоне Vue:

<table>
  <tr><td>hi</td></tr>
</table>

Браузер будет автоматически добавлять <tbody> внутрь <table>, в то время как виртуальный DOM генерируемый Vue не содержит <tbody>, что вызовет несоответствие. Чтобы обеспечить правильное соответствие, обязательно пишите валидный HTML в ваших шаблонах.