发布于 2026-01-05 4 阅读
0

Next.js 垃圾回收课程 - 第 2/3 部分

Next.js 垃圾回收课程 - 第 2/3 部分

亲爱的开发者们,你们好。

非常感谢大家对我们“垃圾处理课程”第一部分(共三部分)的积极评价!😊

这激励我继续写作和研究,以便为大家提供高质量的内容(或者接近高质量的内容😂)。


⭐⭐⭐⭐⭐ 你们都值得拥有这些星星!⭐⭐⭐⭐⭐


我知道今天是星期五📅,所以我保证别在这里浪费时间,好吗?😛

本部分(共三部分)将涵盖哪些内容?

  • 布局,
  • 添加样式(全局样式表和 CSS 模块),
  • 创建自定义的“未找到”页面,
  • 正在重定向。

第五部分 - 布局 🖼️

假设有一个大型应用程序,我们需要在其中使用之前创建的Footer组件Navbar。虽然可以直接将它们添加到每个需要的页面组件中,但这不仅会造成代码重复(不符合DRY 原则),还会使这些组件更难追踪。

为了避免这类问题,我们可以创建布局,用它包裹所有不同的页面,并Layout在整个应用程序中重用该组件。

1- 第一步是Layout在 components 文件夹 ( /components/Layout.js) 中创建组件,并导入我们将用来包装所有组件的组件children

import { Navbar } from './Navbar';
import { Footer } from './Footer';

const Layout = ({ children }) => {
  return (
   {/** We will style it later on :) */}
    <div className="layout-content">      
      <Navbar />
      {children}
      <Footer />
    </div>
  );
};

export default Layout;
Enter fullscreen mode Exit fullscreen mode

第二步是用我们想要应用的布局包裹页面组件。在你的例子中,就是应用程序的根组件/pages/_app.js

import '../styles/globals.css'; // SPOILER OF STYLING 👉👈
import Layout from '../components/Layout'; // We import the Layout

function MyApp({ Component, pageProps }) {
  return (
    <Layout>
      {/** We wrap the root component with the layout.*/}
      {/** and pass it as a children of the Layout component*/}
      <Component {...pageProps} />
    </Layout>
  );
}

export default MyApp;
Enter fullscreen mode Exit fullscreen mode

第三步也是最后一步,是移除首页组件中已导入的页脚和布局组件pages/index.js。(否则它们会出现两次。👯‍♀️)

import Link from 'next/link';

export default function Home() {
  return (
    <div>
      <h1>Hello Next.js</h1>
      <Link href="/about">About</Link>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

就这样!现在布局(包含FooterNavbar)已在我们的应用程序的每个页面上渲染。我知道这只是React些东西,但“知识不占空间”。⚛️ 😃

第六部分 - 添加样式💅

应用程序运行正常,但说实话:它糟透了!👹

与其他 Web 应用程序一样,Next.js我们也可以为其添加样式。有多种global stylesheets方法可以做到这一点,例如使用 `<style>` 、 styled JSX`<style> inline-style`、CSS modules`<style>` 等。现在我们将学习其中的两种方法。

⚆ 全局样式表 ( styles/globals.css)

这个文件包含了我们可以在应用程序任何位置应用的样式。我知道这看起来很合乎逻辑,但我会指出它与CSS modules.

重要提示:我们来这里是为了学习 CSS 样式Next.js,而不是为了精通 CSS 样式,所以请不要妄加评判。😂

@import url('https://fonts.googleapis.com/css2?family=Quicksand:wght@300;400&display=swap');

:root {
  --psy-blue: rgb(188, 152, 255);
  --psy-teal: rgb(3, 129, 129);
}

* {
  box-sizing: border-box;
}

html {
  padding: 0;
  margin: 0;
}

body {
  font-family: 'Quicksand', sans-serif;
  background-color: var(--psy-blue);
  color: var(--psy-teal);
}

.container {
  min-height: 65vh;
}

a {
  color: var(--psy-teal);
  text-decoration: none;
}

.layout-content {
  max-width: 900px;
  margin: 0 auto;
}

nav {
  margin: 10px auto 80px;
  padding: 10px 1px;
  display: flex;
  justify-content: flex-end;
  align-items: flex-end;
  border-bottom: 1px solid var(--psy-teal);
}

nav a {
  margin-left: 10px;
}

nav .brand {
  margin-right: auto;
}

footer {
  display: block;
  text-align: center;
  padding: 30px 0;
  margin-top: 60px;
  color: var(--psy-teal);
  border-top: 1px solid rgb(3, 78, 78);
}
Enter fullscreen mode Exit fullscreen mode

如果你正在疑惑:“我到底是从哪里把这个文件导入到应用程序里的?”,别担心,这不是你的操作,它本来就在文件里pages/_app.js。就是这一行代码……👇

import '../styles/globals.css';
Enter fullscreen mode Exit fullscreen mode

⚇ CSS 模块

允许我们为每个组件编写单独的样式。创建样式表文件后,我们可以将其导入到任何需要的组件中。它会Next.js在类名/选择器名称的末尾添加一些随机字符。

例如:在您的浏览器中(mouse left-click > "Inspect Element"),您应该会看到类似这样的内容:

 <div className="Home_container__2DbTr">...</div>
Enter fullscreen mode Exit fullscreen mode

结尾__2DbTr表示样式仅适用于此组件,因此避免了重复CSS conflicts。您可以将其视为一个unique id

Home我们本可以在组件( )中看到一个例子,该组件在清理之前从文件/pages/index.js中导入了自己的样式。😅styles/Home.module.css

import styles from '../styles/Home.module.css';
Enter fullscreen mode Exit fullscreen mode

添加样式时的快速规则:✏️🗒️

  • CSS Modules必须遵循以下类名命名约定:... ComponentName例如 Home.modules.css)modulescss
  • 如何使用样式:例如,如果您的module.css文件中包含类似以下内容:
.title a {
  color: #0070f3;
  text-decoration: none;
}
Enter fullscreen mode Exit fullscreen mode

您可以通过以下方式应用此样式:

import styles from '../styles/Home.module.css'; // 👈 Importing like mentioned previously
import Link from 'next/link';

export default function Home() {
  return (
    <div className="container">
      <h1>Hello Next.js</h1>
      <div className={styles.title}>
        {/** 👆 applying the styles as shown*/}
        {/** Remember the Link component creates an anchor tag in the DOM* 👇/}
        <Link href="/about">About</Link>
      </div>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

再次记住,<Link>在 DOM 中它只是一个<a>标签。

🧧非常重要的提示selectors必须是纯选择器,换句话说,你必须使用`<select>`class selectorselement selectors不是 `<select>`,因此在你的 CSS 模块中使用以下代码将不起作用,请注意这一点。

a {
  color: #0070f3;
  text-decoration: none;
}
Enter fullscreen mode Exit fullscreen mode

第七部分 - 自定义 404 页面 ❌😵‍💫

如果您尝试访问不存在的路由(例如 `/var/log/` http://localhost:3000/you-are-amazing),Next.js则会收到错误消息default 404 page。很多时候,我们希望自定义路由。
幸运的是,这比您想象的要简单。
在 `pages` 文件夹中,我们只需要创建一个404.js文件,并使用我们刚刚学到的技巧来设置该组件的样式即可。

import Link from 'next/link';

const NotFoundPage = () => {
  return (
    <div className="not-found-page">
      <h1>Page Not Found</h1>
      <p>Looks like this page went on vacation.</p>
      <Link href="/">Home</Link>
    </div>
  );
};

export default NotFoundPage;
Enter fullscreen mode Exit fullscreen mode

现在这个自定义Not Found页面替换了Next.js默认页面。我还添加了一些样式,纯粹是为了好看。🙈

.not-found-page {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  color: rgb(221, 80, 15);
}

.not-found-page h1 {
  font-size: 40px;
  letter-spacing: 1.2rem;
}

.not-found-page p {
  font-size: 26px;
}

.not-found-page a {
  color: rgb(221, 80, 15);
  box-sizing: border-box;
  border: 1px solid rgb(221, 80, 15);
  padding: 2px 20px;
  background-color: rgb(183, 182, 255);
}

.not-found-page a:hover {
  text-decoration: underline;
}
Enter fullscreen mode Exit fullscreen mode

第 8 部分 - 重定向 ♺

有时出于某些原因,我们需要自动将用户重定向到网站上的指定页面。

我们可以设想这样一种情况:一位迷路的用户访问了我们的页面,Not Found Page而我们希望将其重定向到我们的Home页面。让我们使用` <script>`钩子和JavaScript 函数来实现重定向。(你得承认,你上次使用它已经是很久以前的事了吧?🕰️)React's useEffectNext's useRouterSetTimeout()

所以,我们新的 404 页面将如下所示:

import { useEffect } from 'react';
import { useRouter } from 'next/router'; // we import the router
import Link from 'next/link';

const NotFoundPage = () => {
  const router = useRouter(); // initialize it

  useEffect(() => {
    setTimeout(() => {
      router.push('/'); // and define where to redirect
    }, 3000);
  }, []);

  return (
    <div className="not-found-page">
      <h1>Page Not Found</h1>
      <p>Looks like this page went on vacation.</p>
      <Link href="/">Home</Link>
    </div>
  );
};

export default NotFoundPage;
Enter fullscreen mode Exit fullscreen mode

简而言之,the useEffect hook它只会在[]组件的第一次渲染()中运行,并在 3 秒后setTimeout触发重定向到Home页面( ) router.push('/')3000

好了!第二部分(共三部分)就到这里。正如我一开始承诺的那样,我不会过多打扰大家,所以我尽量让过程流畅一些。

本部分(共三部分)将涵盖哪些内容?🤔

  • 静态资源、自定义页面标题和元数据
  • 获取数据
  • 动态路线

看起来只剩下几个主题要讲了,但相信我,它们会占用你大量的时间。我的目标是,在本系列教程结束时,你能够构建自己的Next.js应用程序。

非常感谢大家一路以来的关注。🙏

如果你能从这些帖子中学到一些新东西,我会非常高兴。如果你对目前为止的内容有任何疑问,欢迎随时给我留言,我会尽力用更易懂的方式解释。😃

顺便说一下,我会回复所有评论。虽然回复速度可能不如我希望的那么快,但如果你在我的任何帖子下留言,我保证会尽快回复。🦄

你现在可以走了!最后一部分见。

祝你周末愉快,注意安全!❤️‍

文章来源:https://dev.to/vinicius77/next-js-trash-course-part-2-3-3115