Гидратация клиентской части
Гидратация относится к процессу на стороне клиента, в течение которого 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 в ваших шаблонах.