Next.js实战(下)
这是我参与第五届青训营 伴学笔记创作活动的第8天。
课程重点
- Next.js服务端开发
- Strap创建后端API
- 核心功能讲解
详细知识点
Next.js服务端开发
BFF层:服务于前端的后端,即是中间层,数据是通过调用后端接口而来,在该层并不写生产数据的逻辑,可以理解为是数据的搬运工。和Express、Koa等开发类似,区别是没有参数可以直接区别请求类型。
import type { NextApiRequest, NextApiResponse } from 'next';
import axios from 'axios';
import { CMSDOMAIN } from '@/utils';
import { IArticleProps } from '../article/[articleId]';
const getArticleInfoData = (req: NextApiRequest, res: NextApiResponse<IArticleProps>): void => {
const { articleId } = req.query;
axios.get(`${CMSDOMAIN}/api/article-infos/${articleId}`).then(result => {
const data = result.data || {};
res.status(200).json(data);
});
};
export default getArticleInfoData;
调试方式:
方式一:vscode自带的Debug终端
方式二:启动时命令
yarn debbuger
strapi创建后端api
Strapi 是一个开源的无头 CMS,开发人员可以自由选择他们喜欢的工具和框架,并允许编辑使用他们的应用程序的管理面板来管理和分发他们的内容。基于一个插件系统,Strapi 是一个灵活的 CMS 管理面板和 API 是可扩展的,并且每个部分都是可定制的,以匹配很多使用场景。Strapi 还有一个内置的用户系统,可以详细管理管理员和最终用户可以访问的内容。
创建项目:yarn create strapi-app my-project --quickstart或npx create-strapi-app my-project --quickstart
一个接口的生成有以下几个过程:
- content-type builder 编辑结构体
- content manager 配置数据源,并且发布
- settings roles里面选择对应角色并勾选要发布的接口类型
- 如果涉及嵌套,在接口后加上populate=deep参数(
npm install strapi-plugin-populate-deep --save),没安装加参数populate=*,但只能嵌套一层。
核心功能讲解
下面简单介绍一个文章详情页的实现功能:
- 配置并发布数据源:
- 编写BFF层api:
import type { NextApiRequest, NextApiResponse } from "next";
type ArticleType = {
title: string,
pub_time: string,
content: string
}
export default async function handler(
req:NextApiRequest,
res:NextApiResponse<ArticleType>
) {
const { articleId } = req.query;
const response = await fetch(`http://127.0.0.1:1337/api/articles/${articleId}`,{method:'get',
headers:{'Content-Type': 'application/json'}})
const {data:{attributes:article}} =await response.json();
const {title,pub_time,content} = article
res.status(200).json({
title,pub_time,content
})
}
- 文章页实现
pages/article/[article].tsx
import { NextPage, GetServerSideProps } from "next";
const showdown = require('showdown')
type ArticleType = {
title: string,
pub_time: string,
content: string
}
const Article: NextPage<ArticleType> = ({title,pub_time,content}:ArticleType) => {
const converter = new showdown.Converter();
console.log(title,pub_time,content)
return <div>
<header>{title}</header>
<p>{pub_time}</p>
<div dangerouslySetInnerHTML={{__html:converter.makeHtml(content)}}></div>
</div>
}
export const getServerSideProps: GetServerSideProps = async context => {
const { articleId } = context.query;
console.log('articleId',articleId)
const res = await fetch(`http:127.0.0.1:3000/api/article?articleId=${articleId}`)
const data = await res.json()
console.log(data)
return {
props: data, // 需要拿props包裹
};
};
export default Article
多媒体格式转换:
- markdown转html:
yarn add showdown
const showdown = require('showdown')
const converter = new showdown.Converter();
const html = converter.makeHtml(content)
- html转dom:
dangerouslySetInnerHTML
<div dangerouslySetInnerHTML={{__html:converter.makeHtml(content)}}></div>