一文读懂 Nuxt.js 服务端组件

开发 前端
服务端组件允许在客户端应用程序中对单个组件进行服务端渲染。即使需要生成静态站点,也可以在 Nuxt 中使用服务端组件。这使得构建混合动态组件、服务端渲染的 HTML 甚至静态标记块的复杂站点成为可能。

服务端组件在 Web 开发生态系统中变得越来越普遍。传统上,在单页面应用中,即使是服务端渲染的应用,服务端仅与第一次加载相关,之后将由客户端接管。这意味着 Web 应用的每个部分都必须能够在客户端和服务端上渲染。

相反,服务端组件允许在客户端应用程序中对单个组件进行服务端渲染。即使需要生成静态站点,也可以在 Nuxt 中使用服务端组件。这使得构建混合动态组件、服务端渲染的 HTML 甚至静态标记块的复杂站点成为可能。

事实上,Nuxt 在 React 之前就已经拥有了服务端组件功能。

1、主要优点Summer IS HERE

服务端组件允许从客户端包中提取逻辑

通过将代码移至服务端组件中,这些组件(以及它们使用的组件)不再需要由 Vue 进行水合或“跟踪”。这对于可能不需要在客户端上“重新运行”的复杂或昂贵的操作特别有用,例如应用语法高亮显示或解析 markdown。

在大多数情况下,在 Nuxt 站点中使用服务端组件并不是一个万能的解决方案。相反,当在客户端上渲染组件所需的代码量过多时,这将是一个有用的选项。

服务端组件确保特权代码安全运行

当应用逻辑需要访问数据库、需要私钥或密钥时,服务端组件可以是一个有用的解决方案。它们是区分关注点的一种方式。(注意,还存在其他更好的替代方案,比如将仅限于服务端的代码移入Nitro 服务端路由中,然后由组件进行“获取”)

服务端组件在运行时不一定需要服务器

默认情况下,Nuxt 将预渲染应用中使用的服务端组件。只要渲染了应用的每个页面,并且不只在客户端加载它们,也不在运行时更改 props,服务端组件在完全静态的网站上同样适用。

这意味着可以在静态托管上使用服务端组件,而无需更新到 serverless / edge 渲染。

如果启用了有效载荷提取(在生成/静态站点中默认启用,也可以用于混合部署),那么Nuxt甚至会预取在可能导航到的页面中使用的服务端组件,这样它们将立即加载。

服务端组件可以与普通组件互换

服务端组件可以支持普通组件的所有功能,包括共享状态、访问当前路由等。因为它们的行为就像普通组件一样,所以可以将它们嵌套在服务端组件中,或者将它们零散地分布在其他代码中。

默认情况下,所有插件都将在渲染服务端组件时运行,除非在定义组件时通过设置island: false来明确禁用它们(即将推出的功能)。

2、相似但不同Summer IS HERE

还有其他听起来类似的术语值得一提:

  • React 服务端组件(RSC):这是一种完全不同的渲染服务端组件的方法,通常与从服务端到客户端的流响应相关联。
  • “岛屿”架构: 由 Katie Sylor-Miller 命名,最近因 îles 或 Astro 等框架而流行,这是一种将动态“岛屿”嵌入到更静态的环境中的架构。Nuxt 方法则相反:将静态“岛屿”嵌入到动态 Nuxt 应用中。

3、使用服务端组件Summer IS HERE

那么,如何使用服务端组件呢?

首先,需要启用该功能(因为目前仍处于实验阶段):

// NUXT.CONFIG.TS

export 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>

4、案例:Nuxt Content Summer IS HERE

一个有趣的用例就是创建一个服务端组件,它简单地渲染一个 Nuxt content 页面。假设已经安装了 @nuxt/content,这个神奇的组件就可以将任何路由作为服务端组件进行渲染。

// COMPONENTS/STATIC-MARKDOWN-RENDER.SERVER.VUE
import { 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 })
    }
  }
}

5、路线图Summer IS HERE

下面是 Nuxt 服务端组件的路线图:

  • 远程数据源:很快就可以从其他网站加载服务端组件,能够创建在不同网站中使用的 Nuxt 微服务来渲染组件。
  • '懒加载' 服务端组件:很快就可以在服务端组件加载时显示“回退”内容,以避免阻塞导航。
  • 互动岛屿:已经可以在服务端组件内使用互动客户端插槽,但很快将支持在服务端组件 HTML 中使用任意互动组件。
  • ServerOnly:支持 <ServerOnly> 组件可能会很好,该组件可以自动将标记部分转换为在服务端上渲染的仅服务端部分。

参考https://roe.dev/blog/nuxt-server-components。

责任编辑:姜华 来源: 前端充电宝
相关推荐

2021-04-30 09:32:38

服务端渲染SSR

2019-01-22 15:28:04

Javascriptvue.jsnuxt.js

2023-01-26 00:56:41

Nuxt.js存储库开发

2021-10-15 14:28:30

React 组件渲染

2022-09-21 16:56:16

设计模式微服务架构

2023-12-22 19:59:15

2021-08-04 16:06:45

DataOps智领云

2022-09-22 09:00:46

CSS单位

2022-11-06 21:14:02

数据驱动架构数据

2018-09-28 14:06:25

前端缓存后端

2022-10-20 08:01:23

2022-07-26 00:00:03

语言模型人工智能

2022-12-01 17:23:45

2023-05-20 17:58:31

低代码软件

2022-07-05 06:30:54

云网络网络云原生

2023-11-27 17:35:48

ComponentWeb外层

2021-12-29 18:00:19

无损网络网络通信网络

2019-09-20 09:12:03

服务器互联网TCP

2019-08-20 08:56:18

Linux设计数据库

2021-05-18 09:48:58

前端开发架构
点赞
收藏

51CTO技术栈公众号