样式美化与清理

在上一章中,我们添加了创建帖子和评论的表单。DevShow 还没构建完——还有更多功能要添加——但我们已经构建得足够多了,值得停下来改善设计与用户体验。

目前,用户难以在页面间轻松导航,而且设计看起来很朴素。让我们通过添加合适的导航链接,并用 CSS 为所有内容添加样式,来同时解决这两个问题。

为应用添加样式

让我们先添加 CSS,让 DevShow 看起来更精致。Inertia 入门套件已经包含了一个带有基础样式的 CSS 文件。我们将添加 DevShow 专属的样式,来增强帖子、评论以及整体布局。

打开你的 CSS 文件,并在末尾添加以下样式。

inertia/css/app.css
/* Dev-show styles */
.container {
  max-width: 980px;
  margin: auto;
  padding: 40px 0;
}
.container h1 {
  font-size: 32px;
  letter-spacing: -0.5px;
  margin-bottom: 5px;
}

.post-item {
  padding: 18px 0;
  min-width: 680px;
  border-bottom: 1px solid var(--gray-4);
}

.post-meta {
  display: flex;
  align-items: center;
  margin-top: 8px;
  color: var(--gray-6);
  font-size: 14px;
  font-weight: 500;
  gap: 15px;
}

.post-meta a {
  text-decoration: underline;
}
.post-meta a:hover {
  color: var(--gray-12);
}

.post-item h2 {
  white-space: nowrap;
  display: flex;
  align-items: center;
  gap: 10px;
}

.post-subtext {
  font-size: 16px;
  line-height: 1;
}

.post-actions {
  display: flex;
  gap: 10px;
  margin-bottom: 40px;
  padding: 5px 0;
  align-items: center;
  border-bottom: 1px solid var(--gray-4);
}
.post-actions button {
  padding: 0;
  background: none;
  cursor: pointer;
}

.post {
  min-width: 680px;
  max-width: 800px;
  margin: auto;
}

.post-summary {
  padding: 15px 0;
  border-bottom: 1px solid var(--gray-4);
}

.post-comment-form {
  padding-bottom: 15px;
  margin: 10px 0 40px 0;
  border-bottom: 1px solid var(--gray-4);
}

.post-comment-form textarea {
  width: 100%;
}

.comment-item {
  padding: 18px 0;
  border-bottom: 1px solid var(--gray-4);
}

.comment-actions {
  display: flex;
}
.comment-actions button {
  padding: 0;
  background: none;
  cursor: pointer;
}

.comment-meta {
  color: var(--gray-6);
  font-size: 14px;
  font-weight: 500;
  margin-top: 5px;
}

.posts-list-title {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

这些样式使用了像 var(--gray-4)var(--gray-6) 这样的 CSS 变量,它们已在入门套件的基础样式中定义。它们为 DevShow 提供了统一的间距、排版与配色。

刷新你的浏览器并访问 /posts 。你应该会立刻看到改善后的样式:更好的间距、更干净的边框,以及更易读的排版。

更新首页

目前,首页并没有告诉用户 DevShow 是什么,也不知道如何开始。让我们将其替换为一个合适的着陆页,介绍这个网站并链接到帖子列表。

打开首页组件并替换其内容:

inertia/pages/home.tsx
import { Link } from '@adonisjs/inertia/react'

export default function Home() {
  return (
    <div className="hero">
      <h1>DevShow - Share what you have built</h1>
      <p>
        A small community showcase website to share your creations. Be it a project, tool,
        experiment, or anything they're proud of.
      </p>
      <div>
        <Link route="posts.index" className="button">
          Browse posts created by others
        </Link>
      </div>
    </div>
  )
}

我们使用来自 @adonisjs/inertia/reactLink 组件,并通过 route 属性引用命名路由。className="button" 应用了入门套件 CSS 中的样式。

访问 / 下的首页,你会看到新的着陆页,上面有一个清晰的行动号召按钮,可将用户带到帖子列表。

添加发帖链接

想要分享自己项目的用户,需要一种便捷的方式到达创建表单。让我们在帖子列表顶部添加一个醒目的按钮。

更新你的帖子索引组件,在页头添加该按钮。

inertia/pages/posts/index.tsx
import { InertiaProps } from '~/types'
import { Data } from '@generated/data'
import { Link } from '@adonisjs/inertia/react'

type PageProps = InertiaProps<{
  posts: Data.Post[]
}>

export default function PostsIndex(props: PageProps) {
  const { posts } = props

  return (
    <div className="container">
      <div className="posts-list-title">
        <h1>Posts</h1>
        <Link route="posts.create" className="button">Create new post</Link>
      </div>

      {posts.map((post) => (
        <div key={post.id} className="post-item">
          <h2>{post.title}</h2>

          <div className="post-meta">
            <div>By {post.author.fullName}</div>

            <span>.</span>
            <div>
              <a href={post.url} target="_blank" rel="noreferrer">
                {post.url}
              </a>
            </div>

            <span>.</span>
            <div>
              <Link route="posts.show" routeParams={{ id: post.id }}>
                View comments
              </Link>
            </div>
          </div>
        </div>
      ))}
    </div>
  )
}

posts-list-title 类使用了我们之前添加的 CSS 中的 flexbox,将标题和按钮分别定位在页头的两侧。

访问 /posts ,你会看到右上角出现了新的"Create new post"按钮,让用户能轻松分享他们的项目。

为发帖页面添加导航

当用户处于发帖表单上时,他们可能想返回浏览帖子。让我们在页面顶部添加一个返回链接。

更新你的帖子创建组件:

inertia/pages/posts/create.tsx
import { Form } from '@adonisjs/inertia/react'
import { Link } from '@adonisjs/inertia/react'

export default function PostsCreate() {
  return (
    <div className="form-container">
      <div>
        <Link route="posts.index">
          &lsaquo; Go back to posts listing
        </Link>
        <h1>Share your creation</h1>
        <p>Share the URL and a short summary of your creation</p>
      </div>

      <div>
        <Form route="posts.store">
          {({ errors }) => (
            <>
              {/* ... 表单其余部分 ... */}
            </>
          )}
        </Form>
      </div>
    </div>
  )
}

访问 /posts/create ,你会看到标题上方的返回链接,让导航更加直观。

为帖子详情页添加导航

最后,让我们在单篇帖子页面上添加返回链接,让用户能轻松回到完整列表。

更新你的帖子展示组件:

inertia/pages/posts/show.tsx
import { InertiaProps } from '~/types'
import { Data } from '@generated/data'
import { Form } from '@adonisjs/inertia/react'
import { Link } from '@adonisjs/inertia/react'

type PageProps = InertiaProps<{
  post: Data.Post
}>

export default function PostsShow(props: PageProps) {
  const { post } = props

  return (
    <div className="container">
      <Link route="posts.index">
        &lsaquo; Go back to posts listing
      </Link>
      <div>
        <h1>{post.title}</h1>
      </div>

      <div className="post">
        {/* ... 帖子详情 ... */}
      </div>
    </div>
  )
}

现在访问任意帖子详情页(从 /posts 点击一篇帖子),你就能看到返回链接,从而补全 DevShow 中的导航流程。

你构建的内容

你通过样式与导航改造了 DevShow 的用户体验。以下是你达成的成果:

  • 添加了 CSS,以统一的间距与排版为帖子、评论和整体布局设置样式
  • 用介绍 DevShow 并链接到帖子的 hero 区块更新了首页
  • 在帖子列表上添加了"Create new post"按钮以便访问
  • 在发帖页与详情页上添加了返回导航链接
  • 改善了整体导航流程,让用户能轻松在应用中移动