服务端组件在 Web 开发生态系统中变得越来越普遍。组件传统上,文读务端在单页面应用中,组件即使是文读务端服务端渲染的应用,服务端仅与第一次加载相关,组件之后将由客户端接管。文读务端这意味着 Web 应用的组件每个部分都必须能够在客户端和服务端上渲染。
相反,文读务端服务端组件允许在客户端应用程序中对单个组件进行服务端渲染。组件即使需要生成静态站点,文读务端也可以在 Nuxt 中使用服务端组件。这使得构建混合动态组件、服务端渲染的 HTML 甚至静态标记块的复杂站点成为可能。
事实上,Nuxt 在 React 之前就已经拥有了服务端组件功能。
通过将代码移至服务端组件中,这些组件(以及它们使用的组件)不再需要由 Vue 进行水合或“跟踪”。这对于可能不需要在客户端上“重新运行”的复杂或昂贵的操作特别有用,例如应用语法高亮显示或解析 markdown。
在大多数情况下,在 Nuxt 站点中使用服务端组件并不是一个万能的解决方案。相反,当在客户端上渲染组件所需的代码量过多时,这将是一个有用的选项。
当应用逻辑需要访问数据库、需要私钥或密钥时,服务端组件可以是一个有用的解决方案。它们是区分关注点的一种方式。(注意,还存在其他更好的替代方案,比如将仅限于服务端的代码移入Nitro 服务端路由中,然后由组件进行“获取”)
默认情况下,Nuxt 将预渲染应用中使用的服务端组件。只要渲染了应用的每个页面,并且不只在客户端加载它们,也不在运行时更改 props,服务端组件在完全静态的网站上同样适用。
这意味着可以在静态托管上使用服务端组件,而无需更新到 serverless / edge 渲染。
如果启用了有效载荷提取(在生成/静态站点中默认启用,也可以用于混合部署),那么Nuxt甚至会预取在可能导航到的页面中使用的服务端组件,这样它们将立即加载。
服务端组件可以支持普通组件的所有功能,包括共享状态、访问当前路由等。因为它们的行为就像普通组件一样,所以可以将它们嵌套在服务端组件中,或者将它们零散地分布在其他代码中。
默认情况下,所有插件都将在渲染服务端组件时运行,除非在定义组件时通过设置island: false来明确禁用它们(即将推出的功能)。
还有其他听起来类似的术语值得一提:
那么,如何使用服务端组件呢?
首先,需要启用该功能(因为目前仍处于实验阶段):
// NUXT.CONFIG.TSexport default defineNuxtConfig({ experimental: { componentIslands: true, }})
然后,只需添加 .server.vue 后缀即可将组件“转换”为服务端组件。例如,这是网站页脚的一个版本:
// COMPONENTS/THE-SITE-FOOTER.SERVER.VUE<script lang="ts" setup>const links = [ { name: 'GitHub', icon: 'i-ri:github-fill', link: 'https://github.com/', }, // ...]const year = new Date().getFullYear()</script><template> <div> <footer> <small> © 2020-{ { year }} Github. </small> <ul> <li v-for="{ link, name, icon } in links"> <a :href="link" rel="me"> <span class="h-4 w-4 fill-current" :class="icon" alt="" /> <span class="sr-only"> { { name }} </span> </a> </li> </ul> </footer> </div></template>
这些内容都是静态的,所以非常适合适合使用服务端组件来实现。只需要在文件名后面添加.server
后缀就可以了,而使用的方式与以前完全相同。
<template> <div> <LayoutTheSiteHeader /> <NuxtPage /> <LayoutTheSiteFooter /> </div></template>
一个有趣的用例就是创建一个服务端组件,它简单地渲染一个 Nuxt content 页面。假设已经安装了 @nuxt/content,这个神奇的组件就可以将任何路由作为服务端组件进行渲染。
// COMPONENTS/STATIC-MARKDOWN-RENDER.SERVER.VUEimport { h } from 'vue'import { ContentRendererMarkdown } from '#components'export default defineComponent({ props: { path: String, }, async setup(props) { if (process.dev) { const { data } = await useAsyncData(() => queryContent(props.path!).findOne() ) return () => h(ContentRendererMarkdown, { value: data.value! }) } const value = await queryContent(props.path!).findOne() return () => h(ContentRendererMarkdown, { value }) },})
然后,这样来使用它:
<template> <StaticMarkdownRender path="/" /></template>
目前, <NuxtLink> 组件不是交互式的,这意味着可能需要在父页面中添加一些类似这样的代码,作为客户端路由的“假装”版本:
import { parseURL } from 'ufo'function handleNavigationClicks(e: MouseEvent | KeyboardEvent) { const anchor = (e.target as HTMLElement).closest('a') if (anchor) { const href = anchor.getAttribute('href') if (href) { e.preventDefault() const url = parseURL(href) if (!url.host || url.host === 'roe.dev') { return navigateTo(url.pathname) } return navigateTo(href, { external: true }) } }}
下面是 Nuxt 服务端组件的路线图:
参考:https://roe.dev/blog/nuxt-server-components。
责任编辑:姜华 来源: 前端充电宝 服务端组件客户端(责任编辑:时尚)
海关总署:前10个月煤、天然气进口量价齐升 进口铁矿砂9.33亿吨
湖北石首长江公路大桥北岸主塔成功封顶 预计2019年底建成通车
*ST海航(600221.SH):2月客运量同比升419.17% 货邮载运率32.77%
屏下指纹概念股有哪些?去年全球屏下指纹手机出货量约为2.0亿台