前言
在《Astro+Vue3+Nest+TS 搭建服务端渲染 SSR》和《Nestjs 与使用》中,我们已经搭建好了基础工程,详细介绍了如何使用 Nestjs 构建一个 Restful api 服务,这篇接着介绍如何使用 Astro 构建《Remy 学习与应用》的 SSR 笔记展示端。
Astro
Astro 是集多功能于一体的 Web 框架,用于构建快速、以内容为中心的网站。
主要特性
- 组件群岛: 用于构建更快网站的全新 web 架构。
- 服务器优先的 API 设计: 移除客户端上高资源消耗的激活过程。
- 默认零 JS: 没有 JavaScript 运行时开销来减慢你的速度。
- 边缘就绪: 在任何地方部署,甚至像 Deno 或 Cloudflare 这样的全球边缘运行时。
- 可定制: Tailwind, MDX 和 100 多个其他集成可供选择。
- 不依赖特定 UI: 支持 React, Preact, Svelte, Vue, Solid, Lit 等等。
目录结构
/
├── public/
│ └── favicon.ico
├── src/
│ ├── assets/
│ │ └── vditor/
│ ├── components/
│ │ └── *.astro
│ ├── layouts/
│ │ └── Layout.astro
│ └── pages/
│ ├── api/
│ │ ├── dict.ts
│ │ └── artile.ts
│ ├── article/
│ │ ├── [...id].astro
│ │ └── index.astro
│ └── index.astro
├── .env[.development/production]
├── astro.config.mjs
├── tsconfig.json
└── package.json
public/
放 web 端静态资源
src/assets/
放 web 端非静态资源
src/components/
放组件,可以是 Astro、React、Preact、Svelte、Vue、SolidJS、AlpineJS、Lit、Markdown
src/layouts/
放主体页面骨架
src/pages/
在未开启 SSR 的 SSG 静态模式时,该目录放的文件将生成静态文件端点;在 SSR 服务端渲染模式时,api 目录下的文件中以 Http 的请求方式(GET、POST 等)作为函数名的方法将生成对应的 restful api,非 api 目录下的 .astro
or .md
文件将生成相应的 SSR 页面。
页面编写
在 src/pages/article
目录下新建页面文件 [id].astro
或者[...id].astro
(后者以剩余参数命名,更灵活,可以匹配任何深度的文件路径),它将生成一个可访问的 web 动态路由 /article/:id
,访问链接http://localhost:4321/article/1
将解析到 id 参数为 1,代码如下:
---
import Layout from '../../layouts/Layout.astro'
import Article from '../../components/Article.vue'
import * as api from '../api/article'
const res = await api.detail(Astro, import.meta.env.PUBLICK_API_PATH)
const data = await res.json()
if (data.code === 404) {
return Astro.redirect('/404')
}
const article = data.data
---
<Layout title={article.title + '-Remy笔记'} desc={article.desc} menu="article">
<Article data={article} />
</Layout>
<style is:global>
main {
background-color: #fff;
}
</style>
Astro 中.env 配置文件定义的环境变量,仅以PUBLICK_
开头的才能在客户端代码通过import.meta.env.
的方式访问。
两个 ---
之间编写业务逻辑,它将运行在 SSR 服务端,这里定义的变量可以在 HTML 模板中使用,模板语法和 JSX
类似。样式仍然放在 style 标签内,默认自动限定范围,可以使用 CSS 预处理器,如 Sass、Stylus 和 Less。
这里列举两个 Astro 模板和
JSX
语法的关键区别:
- 在 Astro 中,所有 HTML 属性都使用标准的 kebab-case 格式,而不是 JSX 中使用的 camelCase。这甚至适用于 class,而 React 不支持。
- 一个 Astro 组件模版可以渲染多个元素,无需像 JavaScript 或 JSX 那样将所有内容都包装在单个
<div>
或<>
中。
下面是主体骨架 Layout.astro 的部分代码:
---
import Header from '../components/Header.vue'
interface Props {
title: string
desc: string
menu?: string
}
const { title, desc, menu } = Astro.props
---
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>{title}</title>
<meta name="keywords" content={title} />
<meta name="description" content={desc} />
<meta
name="viewport"
content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no"
/>
<link rel="icon" href="/favicon.ico" />
<meta name="generator" content={Astro.generator} />
</head>
<body>
<Header active={menu} />
<div class="body-con">
<slot />
</div>
</body>
</html>
服务器端点
因为《Remy 学习与应用》使用的 Nestjs 构建 restful api 服务,所以没有用 Astro 的服务器端点,api 目录下的文件仅作为普通函数使用。这里简单举个例子:
import { APIRoute } from 'astro'
export const GET: APIRoute = ({ params, request }): Response => {
return new Response(
JSON.stringify({
message: 'This was a GET!',
})
)
}
开启 SSR 时,(仅限以 Http 请求方式作为函数名的方法)会被发布成 restful api:GET /api/dict
在 Astro 组件中调用
---
const res = await api.GET(Astro)
const data = await res.json()
---
<div>{data.message}</div>
也可以在其他地方用 ajax 请求接口(不过,这种方式接口入参似乎是空对象,需要自行从 request 解析)
const res = await fetch('/api/dict?parentId=1')
const data = await res.json()
启动/打包
启动 npm start
即 astro dev
打包 npm build
即 astro build
结束语
因个人知识面的局限性,如有不正确或异议的地方,望大家指正。
以后的学习笔记和实践示例将持续添加到《Remy 学习与应用》。
感兴趣的同学可以订阅专栏,关注博主,一起学习进步。
如若转载,请注明出处:https://blog.csdn.net/remy0817/article/details/133341894