VueJS: Hydrat hóa phía máy khách
Hydration đề cập đến quá trình phía máy khách, trong đó Vue tiếp nhận HTML tĩnh được gửi bởi máy chủ và biến nó thành DOM động có thể phản ứng với các thay đổi dữ liệu phía máy khách.
Trong entry-client.js
, chúng ta chỉ đơn giản là gắn các ứng dụng với dòng này:
// giả sử rằng phần tử template gốc là App.vue có `id="app"` app.$mount('#app')
Vì máy chủ đã kết xuất đánh dấu, chúng ta rõ ràng không muốn bỏ đi và tạo lại tất cả các phần tử DOM. Thay vào đó, chúng ta muốn "hydrate" đánh dấu tĩnh và làm cho nó tương tác.
Nếu bạn kiểm tra đầu ra của máy chủ, bạn sẽ thấy rằng phần tử gốc của ứng dụng đã có một thuộc tính đặc biệt được thêm vào:
<div id="app" data-server-rendered="true">
Các thuộc tính data-server-rendered
đặc biệt cho phép các Vue client-side biết rằng đánh dấu được đưa ra bởi các máy chủ và nó sẽ gắn kết trong chế độ hydrat hóa. Lưu ý rằng nó không thêm id="app"
, chỉ là thuộc tính data-server-rendered
: bạn cần thêm ID hoặc một số bộ chọn khác vào chính phần tử gốc của ứng dụng hoặc ứng dụng sẽ không hydrat đúng cách.
Lưu ý rằng trên các phần tử không có thuộc tính data-server-rendered
, thì quá trình hydrat hóa cũng có thể bị ép buộc bằng cách truyền true
tới đối số hydrating
của $mount
:
// Ép buộc hydrat hóa của ứng dụng app.$mount('#app', true)
Trong chế độ development, Vue sẽ xác nhận cây DOM ảo được tạo phía máy khách khớp với cấu trúc DOM được hiển thị từ máy chủ. Nếu có sự không phù hợp, nó sẽ bảo vệ hydrat hóa, loại bỏ DOM hiện có và hiển thị từ đầu. Trong chế độ production, xác nhận này bị tắt để tạo hiệu suất tối đa.
#Hydration Caveat
Một điều cần lưu ý khi sử dụng SSR + client hydrat hóa là một số cấu trúc HTML đặc biệt có thể bị thay đổi bởi trình duyệt. Ví dụ, khi bạn viết điều này trong một mẫu Vue:
<table> <tr><td>hi</td></tr> </table>
Trình duyệt sẽ tự động chèn vào <tbody>
bên trong <table>
, tuy nhiên, DOM ảo được tạo bởi Vue không chứa <tbody>
, vì vậy nó sẽ gây ra sự không khớp. Để đảm bảo đối sánh chính xác, hãy đảm bảo viết HTML hợp lệ trong các template của bạn.