所谓客户端激活,指的是vue在浏览器接管由服务端发送的静态html,使用基变为由vue管理的动态dom的过程。 在entry-client.js中,会先用下面这行挂载(mount)应用程序 app.$mount('#__nuxt')由于服务器已经渲染好HTML,显示无需将其丢弃再重新创建所有的DOM元素。但这些HTML是静态的,所以我需要"激活"将他们成为动态的(能够响应后缀的数据变化) 激活的开始和结束在nuxt3框架中,客户端的激活从接到到HTML-->加载资源js脚本 --> 加载nuxt3插件之后就开始了。 直到vue的生命周期的onMounted之后才结束。 Hydration Mismatch(激活不匹配)在激活的过程中会将服务端预渲染的HTML的DOM结构与客户端挂载前渲染的DOM结构,如何发现结构不匹配,就出抛出Hydration Mismatch 的错误。 为避免这个错误,请遵守如下规则: 1. 组件模块中要避免存在不答规范的HTML结构。 不规范的HTML结构会被浏览器自动矫正,这就会导致客户端期望的HTML结构与服务端的不一致。 2. 渲染的数据中避免包含随机生成的值,由于setup中的代码在服务端和客户端都会执行一次,即代码是共享的。由于是随机的,所以客户端和服务端生成的页面数据极可能是不一样的,从而会导致不匹配的问题。 3. 避免在setup中请求不同参数的接口数据,不同参数或相同参数都有可能会出现服务端请求时返回的数据与客户端请求返回的数据不一样,从而导致不匹配的问题。 当 Vue(nuxt3底层ssr使用的是vue的ssr) 遇到激活不匹配时,它将尝试自动恢复并调整预渲染的 DOM 以匹配客户端的状态。这将导致一些渲染性能的损失,因为需要丢弃不匹配的节点并渲染新的节点,但nuxt3考虑到性能问题,并不会尝试恢复。所以最好还是在开发过程中发现并避免激活不匹配。 useHydration此方法是框架内部提供的,主要是用来在客户端获取服务端设置数据。 方法定义 useHydration <T> (key: string, get: () => T, set: (value: T) => void) => {}此方法可以在组合式API、插件和组件中使用。
方法实现 此方法的实现也是非常简单 import { useNuxtApp } from "../nuxt.mjs";export const useHydration = (key, get, set) => { const nuxt = useNuxtApp(); if (process.server) { // 如果是在服务端,则在渲染完成后,将数据存放到payload中, // payload的所有数据会和渲染好的HTML文本一起发送给客户端。 nuxt.hooks.hook("app:rendered", () => { nuxt.payload[key] = get(); }); } if (process.client) { // 在客户端中,当vue实例创建后,就可以获取在服务端保存的数据了。 nuxt.hooks.hook("app:created", () => { set(nuxt.payload[key]); }); } }; 示例 //plugins/hydrationtest.vue// 由于客户端获取数据是在vue实例创建之前, // 所以在插件中才能看到数据获取的日志打印 // 即客户端激活是从vue实例创建之后开始的。 import { useHydration } from '#app' export default defineNuxtPlugin(nuxtApp => { try { useHydration("test", () => { console.log("set data in server side") return "set by server side" }, (value) => { console.log("client get data from server = " + value) }) } catch (e) { console.log(e) } }
|
万奢网手机版
官网微博:万奢网服务平台