“岛屿”架构: 由 Katie Sylor-Miller 命名,最近因 îles 或 Astro 等框架而流行,这是一种将动态“岛屿”嵌入到更静态的环境中的架构。Nuxt 方法则相反:将静态“岛屿”嵌入到动态 Nuxt 应用中。
// NUXT.CONFIG.TS export default defineNuxtConfig({ experimental: { componentIslands: true, } })然后,只需添加 .server.vue 后缀即可将组件“转换”为服务端组件。例如,这是网站页脚的一个版本:
// 堆代码 duidaima.com // 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 Summer IS HERE
// 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 }) } } }五、路线图Summer IS HERE