Next.js项目实践(三)– 问题详细页面

本文根据项目路线实现问题详细页面浏览的功能。


显示问题列表

首先我们显示问题列表,在 app/issues/page.tsx中,使用prisma客户端获取数据库列表,然后用Radix UI的Table组件列出清单,列表显示三列:Issue、Status、CreateAt。修改Table.Root的 variant属性为“surface”,美化表格显示灰色标题和圆的边角。

按钮与表格目前靠得太近了,我们将Button放在div里,设置 mb-5,表示底部间隔设为5。

查看页面,还不错。

现代的开发首先要适应移动端,我们看看移动端效果如何?

移动端明显有点被压扁了,我们需要调整!如何调?

可以只显示一列Issue!隐藏其他两列。

另外我们希望看到Status,可以显示在Issue标题下方。

看看实际效果,我们看到在移动端(小屏)只能看到1列。

提交Git,命名:Show the issues.


构建问题状态徽章

目前状态(Status)是纯文本显示的,有点单调,可以使用Badge美化显示。Radix UI关于Badge的说明。

https://www.radix-ui.com/themes/docs/components/badge

由于状态徽章在多处使用到,我们在components目录下新建IssueStatusBadge.tsx文件。

使用Typescript的Record将 Status类型 与 在Badge中展示需要的对象{label, color} 进行映射,这样我们传递过去 Status(OPEN|IN_PROGRESS|CLOSED) 就能展示相应的Badge了。我们注意到,Status是在Prisma建立Issue模型时定义的,这里也可以用(建的模型如Issue也是可以作为类型在这里使用的)。

为了查看效果,我们在数据库里修改某些记录的状态IN_PROGRESS和CLOSED,查看网页。

提交Git,命名:Build the issue status badge.


添加加载框架

在列表未加载完成之前,显示页面骨架,是现代应用常见的做法,能提升用户体验。

新建loading.tsx文件,这个文件名是约定的。延时模拟加载过程,这样就能更好地查看加载的页面,需要安装delay:npm i delay。loading.tsx文件也简单显示loading信息。

目前的加载页面。

再来修改loading.tsx,使之显示 skeleton,安装库:

npm i react-loading-skeleton@3.3.1

谷歌搜索 “react loading skeleton” ,查看使用说明。

https://www.npmjs.com/package/react-loading-skeleton

从实际的页面复制相关表格代码,表body由skeleton代替。并将按钮组件提取出来形成IssueAction.tsx,在loading.tsx和page.tsx中调用,免得重复编码。

目前加载的页面就非常专业体验也很好。

提交Git,命名:Add loading skeletons.


显示问题详细信息

显示问题详细页面,需要动态路径,新建[id]目录,再在其下新建page.tsx,创建IssueDetailPage组件。该组件接收 id 参数,并根据id从数据库获取详细信息,注意动态路径的参数都是String类型的,所以id要转成数值再去数据库查询。数据库找不到记录这里直接使用notFound()函数。

我们在IssuesPage上添加链接.

目前IssueDetailPage的效果。

我们发现,访问 /issues/1等问题详细页面时,也会显示前面列表页的skeleton,显然是不合适的,原因是我们的loading.tsx建在 /issues 下,子级的 /issues/1 也同样有效。解决这个问题可以在 /issues/[id]下也创建loading.tsx覆盖父级,同样的, /issues/new下也需创建loading.tsx。

提交Git,命名:Show issue details


设置问题详细信息页面的样式

用Radix UI 样式化详细信息页面:

Title, 使用Heading,属性 as=”h2″ 设置字体稍小一些;Status, 使用 Badge; CreateAt, 使用Text。

Status 和 CreateAt 水平放置,使用Flex。

Description, 使用Card包裹起来。

查看页面。

提交Git,命名:Style the issue detail page.


添加 Markdown 预览

添加一条问题,并使用Markdown编辑。

提交保存之后,浏览这条问题,发现是纯文本的。

我们需要安装react-markdown库。

npm i react-markdown@8.0.7

另外还需要安装typography插件。搜索 “tailwind typography” ,找到下面这个说明。

https://tailwindcss.com/docs/typography-plugin

安装: 

npm install -D @tailwindcss/typography

再到tailwind.config.ts文件,添加@tailwindcss/typography插件;然后回到IssueDetailPage, 用ReactMarkdown组件将Description包起来,并添加 prose 的class.

再查看问题详细页面,就能预览Markdown了。

提交Git,命名:Add markdown preview.


其他Loading Skeletons

/issues/[id] 加载页面是简单的文本信息Loading, 我们也添加Skeleton,先从page.tsx复制代码,并将div改成Box(为了Radix UI的一致)。然后用skeleton填充。Skeleton默认占用所有可用空间,我们在Box添加了max-w-xl限制了宽度。

查看网页效果。

同样的,/issues/new 也添加Skeleton加载页面。高度暂估设了20rem。

提交Git,命名:Add additional loading skeletons.


禁用SSR

不管是服务端组件还是客户端组件,都会先在服务器端进行预渲染(SSR),我们可以禁用SSR。对于Markdown组件,我们可以使用延迟加载并设置ssr为false。

提交Git,命名:Disable SSR for loading md editor


重构:组织Imports

components目录里有了一些组件,其他页面使用这些组件时需明确指定,可以用 index.ts将他们组织在一起。

components目录下新建 index.ts. 并将组件导入到这个文件里。

其他页面调用组件时,只需指定 components目录即可。

我们看到,index.ts是先导入(import),然后逐个进行导出(export)。这是可以合并简化的。

加载页面(loading.tsx)使用Skeleton,都需要导入Skeleton以及与之配套的css,可以组织到 index.ts中。

在components目录新建Skeleton.tsx文件,并导入Skeleton和CSS,然后默认导出Skeleton。

这样,loading.tsx使用Skeleton时只需导入Skeleton即可。

提交Git,命名:Refactor: Organize import statements


小结

本文根据项目路线图实现了查看问题详细页面的功能。

下一篇实现问题的更新功能。

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注