从零开始编写博客网站:在Next.js中路由

作者 : IT 大叔 本文共4232个字,预计阅读时间需要11分钟 发布时间: 2020-11-9

尽管此文章是系列文章的一部分,但其目的是使该文章能够独立存在,即使您不遵循该系列教程,您也应该能够学到一些知识。如果您有兴趣,教程系列将从这里开始:第1部分


先决条件

第1部分中介绍了本教程的先决条件。


基本路由

Next.js中的路由是通过保持文件夹结构的方式构造的,以使您的页面可以在浏览器中访问。正如我们在本教程的上半部分所看到的,我们能够访问网站的根目录,这是因为我们index.jspages目录中有一个文件。

文件名index.js在Next.js中是特殊的,当您转到子文件夹的根目录时,文件名即会提供,如下所示:

  • pages/index.js ->可在以下位置访问 /
  • pages/blog/index.js ->可在以下位置访问 /blog

由于我们正在构建博客,因此我们创建该pages/blog/index.js文件。blogpages目录内创建一个名为目录的文件夹,并index.js在其中创建文件:

复制
const BlogPage = () => {
  return "This is the blog page!";
};

export default BlogPage;

如果通过运行现在运行你的项目yarn dev,你会发现,如果你去的http://本地主机:3000,你会看到的内容,pages/index.js但如果你不是参观的http://本地主机:3000 /博客,你会迎接这是博客页面!

基本路由很酷,但是当我们要构建可以由内容驱动的动态路由时,它并没有用。让我们创建一个可用于博客文章的动态路由。


动态路由

与基本路由如何使用目录中的文件夹和文件结构相似,pages动态路由也是如此。

可以通过如下命名文件来构建动态路由:[slug].js。让我们创建pages/blog/[slug].js并查看其实际作用。

如果我们转到http:// localhost:3000 / blog,我们会看到它仍然有效,那很好,我们仍然希望能够导航到该/blog路线。

[slug].js命名模式使得它使我们可以动态生成时登记的路线,让我们添加一些代码,我们的[slug].js文件,看看我们如何能够利用这样的:

复制
const BlogPost = (props) => JSON.stringify(props);

export default BlogPost;

// This function is ran by Next.js to determine which 
// paths need to be created dynamically, here we've
// hardcoded one path that will be served when the
// slug matches "my-first-blog-post"
export async function getStaticPaths() {
  return {
    paths: [{ params: { slug: "my-first-blog-post" } }],
    fallback: false,
  };
}

// params in getStaticPaths({params}) are from getStaticPaths.
// Next.js runs this function to determine what props to
// pass to our React component.
// In this case we see that we only have one possible path
// and that is the path to "my-first-blog-post".
export async function getStaticProps({ params }) {
  return { props: { slug: params.slug } };
}

现在访问http:// localhost:3000 / blog / my-first-blog-post会显示传递给BlogPost组件的道具,并且应该显示给您{"slug":"my-first-blog-post"}。如我们所见,我们有一个名为的道具slug。这是从getStaticProps功能。如果尝试其他路径,而该路径未在getStaticPaths函数中指定,则我们会注意到它给出了404响应。所有使用的动态路由getStaticProps必须由指定getStaticPaths

有关此的更多信息:


根据我们的博客文章创建路径

在上一节中,我提到getStaticPaths如果使用getStaticProps,则必须在其中指定所有动态路径,这是正确的,但是手动完成所有这些操作没有用,因为它很快就会变得乏味。让我们创建一种基于一些虚假博客帖子定义这些路线的方法。

pages目录中,创建一个名为的文件_posts.js,我们将使用该文件来定义帖子。现在,这些将被硬编码,在本系列的后续部分中,我们将阅读Markdown文件并基于这些文件生成我们的帖子。

顺便说一句,您现在可能会看到一种模式,还记得文件名为_app.js?该_posts.js文件类似于我们刚创建的文件。Next.js不会将以下划线开头的文件解释为可访问的页面。

让我们pages/posts.js看起来像这样:

复制
// Hardcoded for now to demonstrate dynamic routing.
// We'll generate this list based on Markdown files
// in a later part of this tutorial series
const posts = [
  {
    title: "My first blog post!",
    slug: "my-first-blog-post",
    date: "2020-11-05",
  },
  {
    title: "My second blog post!",
    slug: "my-second-blog-post",
    date: "2020-11-06",
  },
];

export default posts;

并修改pages/blog/[slug].js文件以使用此新_posts.js文件:

复制
import posts from "../_posts";

// This post argument is passed from getStaticProps
const BlogPost = ({ post }) => (
  <article>
    <h1>{post.title}</h1>
    <p>{post.date}</p>
  </article>
);
export default BlogPost;

export async function getStaticPaths() {
  return {
    // Map all the posts to objects with the slug in the params object
    // since we want all our pages to be accessible, the paths array
    // needs to contain a list of all the posts slugs
    paths: posts.map((post) => ({ params: { slug: post.slug } })),
    fallback: false,
  };
}

export async function getStaticProps({ params }) {
  return {
    props: {
      // Since our slug should be unique we can use
      // it to find the post with the matching slug,
      // this will be the post we need to render
      post: posts.find((post) => post.slug === params.slug),
    },
  };
}

在上面的代码片段中,React似乎缺少导入功能,但是Next.js实际上让我们跳过了此声明。

让我们也使我们的http:// localhost:3000 / blog页面更加有用:

复制
import Link from "next/link";
import posts from "../_posts";

const BlogPage = ({ posts }) => (
  <ul>
    {posts.map((post) => (
      <li key={post.slug}>
        <Link href={`blog/${post.slug}`}>
          <a>{post.title}</a>
        </Link>
      </li>
    ))}
  </ul>
);

export default BlogPage;

export async function getStaticProps() {
  return {
    props: {
      posts,
    },
  };
}

创建导航栏

虽然我们的页面有效,但往返博客帖子确实很烦人,我们的主页甚至都无法使用,它只是说Home sweet home。让我们添加一个导航栏,该导航栏显示在每个子页面(包括主页)上。

为此,我们可以修改pages/_app.js文件。将为每个页面运行此文件,并且将在所有页面中运行此组件中存在的代码。有关该pages/_app.js文件的更多信息,您可以查看本教程系列中的上一个条目,或在此处阅读更多内容。

修改您pages/_app.js的外观,如下所示:

复制
import Link from "next/link";
import "../styles/globals.css";

function MyApp({ Component, pageProps }) {
  return (
    <>
      <nav>
        <ul>
          <li>
            <Link href="/">
              <a>Home</a>
            </Link>
          </li>
          <li>
            <Link href="/blog">
              <a>Blog</a>
            </Link>
          </li>
        </ul>
      </nav>
      <Component {...pageProps} />
    </>
  );
}

export default MyApp;

现在尝试您的应用程序,浏览一下,您应该会看到页面顶部始终存在指向Home和Blog的链接,您可以使用这些链接来浏览,类似地,您也可以从Blog导航到博客文章。页。


现在,我们有一个Next.js基于数据集支持动态路由的应用程序,可用于本系列教程的下一部分。

这是我的项目在现阶段的样子:https : //github.com/simon-nystrom/nextjs-blog-example/tree/p2

希望您会继续学习本教程,请随时询问您是否有任何疑问,或者告诉我是否错过了什么!

免责声明:
1. 本站资源转自互联网,源码资源分享仅供交流学习,下载后切勿用于商业用途,否则开发者追究责任与本站无关!
2. 本站使用「署名 4.0 国际」创作协议,可自由转载、引用,但需署名原版权作者且注明文章出处
3. 未登录无法下载,登录使用金币下载所有资源。
IT小站 » 从零开始编写博客网站:在Next.js中路由

常见问题FAQ

没有金币/金币不足 怎么办?
本站已开通每日签到送金币,每日签到赠送五枚金币,金币可累积。
所有资源普通会员都能下载吗?
本站所有资源普通会员都可以下载,需要消耗金币下载的白金会员资源,通过每日签到,即可获取免费金币,金币可累积使用。

发表评论