本文根据项目路线实现问题详细页面浏览的功能。
显示问题列表
首先我们显示问题列表,在 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
小结
本文根据项目路线图实现了查看问题详细页面的功能。
下一篇实现问题的更新功能。