这是我参与「第五届青训营 」伴学笔记创作活动的第 9 天
资产、元数据和 CSS
我们当前添加的第二个页面没有样式。让我们添加一些CSS来设置页面样式。
接下来.js内置了对CSS和Sass的支持。 在本课程中,我们将使用 CSS。
本课还将讨论 Next.js 如何处理静态资产(如图像)和页面元数据(如标记)。
您将在本课中学到什么
在本课程中,您将学习:
- 如何将静态文件(图像等)添加到 Next.js。
- 如何为每个页面自定义内部的内容。
- 如何创建一个使用 CSS 模块设置样式的可重用 React 组件。
- 如何在页面/_app.js中添加全局 CSS。
- 在Next.js中设置样式的一些有用提示。
先决条件
- 基本的CSS知识。本课程将介绍如何在Next.js应用程序中添加CSS,但不会涵盖CSS基础知识。
资产
接下来.js可以在顶级公共目录下提供静态资产,例如图像。里面的文件可以从应用程序的根目录引用,类似于页面。public
该目录对于 、Google 站点验证和任何其他静态资产也很有用。查看静态文件服务的文档以了解更多信息。publicrobots.txt
下载您的个人资料图片
首先,让我们检索您的个人资料图片。
- 以格式下载您的个人资料图片(或使用此文件)。.jpg
- 在公共目录中创建一个目录。images
- 将图片保存在目录中。profile.jpgpublic/images
- 图像大小可以在 400 像素 x 400 像素左右。
- 您可以直接在公共目录下删除未使用的 SVG 徽标文件。
未优化的图像
使用常规 HTML,您可以按如下方式添加您的个人资料图片:
<图像 src="/images/profile.jpg" alt="Your Name" />
但是,这意味着您必须手动处理:
- 确保您的图像在不同的屏幕尺寸上具有响应性
- 使用第三方工具或库优化图像
- 仅在图像进入视口时加载图像
等等。相反,Next.js 提供了一个开箱即用的组件来为您处理此问题。Image
图像组件和图像优化
next/image 是 HTML 的扩展<图像> 元素,为现代网络而发展。
Next.js 默认情况下还支持图像优化。这允许在浏览器支持时以现代格式(如 WebP)调整大小、优化和提供图像。这样可以避免将大型图像传送到具有较小视口的设备。它还允许Next.js自动采用未来的图像格式,并将其提供给支持这些格式的浏览器。
自动图像优化适用于任何图像源。即使图像由外部数据源(如 CMS)托管,仍可对其进行优化。
使用图像组件
Next.js 不是在构建时优化映像,而是根据用户请求按需优化映像。与静态站点生成器和仅静态解决方案不同,无论是发布 10 个图像还是 10 万个图像,您的构建时间都不会增加。
默认情况下,图像是延迟加载的。这意味着您的页面速度不会因视口外的图像而受到影响。图像在滚动到视口时加载。
图像始终以避免累积布局偏移的方式呈现,这是Google将在搜索排名中使用的核心Web至关重要。
下面是一个使用 next/image 显示我们的个人资料图片的示例。和道具应该是所需的渲染大小,纵横比与源图像相同。heightwidth
**注意:**我们稍后将在“抛光布局”中使用此组件,暂时不需要复制它。
import Image from 'next/image'; const YourComponent = () => ( <Image src="/images/profile.jpg" // Route of the image file height={144} // Desired size with correct aspect ratio width={144} // Desired size with correct aspect ratio alt="Your Name" /> );
要了解有关自动图像优化的更多信息,请查看文档。
要了解有关该组件的更多信息,请查看下一个/图像的 API 参考。Image
元数据
如果我们想修改页面的元数据,例如 HTML 标记,该怎么办?<br /><title>是 HTML 标记的一部分,因此让我们深入了解如何在 Next.js 页面中修改标记。在编辑器中打开并找到以下行:pages/index.js
<Head>
<title>Create Next App</title>
<link rel="icon" href="/favicon.ico" />
</Head>
请注意,使用Head代替小写。 是一个内置于 Next.js 中的 React 组件。它允许您修改页面的。
您可以从 next/head 模块导入组件。
添加到Headfirst-post.js
我们尚未在路线中添加 a。让我们添加一个。/posts/first-post打开文件并在文件开头添加 from 的导入:pages/posts/first-post.jsHead
import Head from 'next/head';
然后,更新导出的组件以包含该组件。现在,我们只添加标签:FirstPostHeadtitle
export default function FirstPost() {
return (
<>
<Head>
<title>First Post</title>
</Head>
<h1>First Post</h1>
<h2>
<Link href="/">← Back to home</Link>
</h2>
</>
);
}
尝试访问 http://localhost:3000/posts/first-post。浏览器选项卡现在应该显示“First Post”。通过使用浏览器的开发人员工具,您应该会看到标记已添加到 。title
第三方 JavaScript
第三方 JavaScript 是指从第三方源添加的任何脚本。通常 包含第三方脚本是为了将较新的功能引入不 需要从头开始编写,例如分析、广告和客户支持小部件。
添加第三方 JavaScript
让我们深入了解如何将第三方脚本添加到 Next.js 页面。
在编辑器中打开并找到以下行:pages/posts/first-post.js
<Head>
<title>First Post</title>
</Head>
除了元数据之外,通常会添加需要尽快加载和执行的脚本 在页面中。使用常规 HTML
<Head>
<title>First Post</title>
<script src="https://connect.facebook.net/en_US/sdk.js" />
</Head>
此脚本包含通常用于引入Facebook社交插件和其他功能的Facebook SDK。虽然这 方法有效,以这种方式包含脚本并不能清楚地了解何时加载 关于在同一页面上获取的其他 JavaScript 代码。如果特定脚本是 呈现阻塞并可能延迟页面内容的加载,这可能会显著影响性能。
使用脚本组件
next/script 是 HTML 的扩展
import Script from 'next/script';
现在,更新组件以包含组件:FirstPostScript
export default function FirstPost() {
return (
<>
<Head>
<title>First Post</title>
</Head>
<Script
src="https://connect.facebook.net/en_US/sdk.js"
strategy="lazyOnload"
onLoad={() =>
console.log(`script loaded correctly, window.FB has been populated`)
}
/>
<h1>First Post</h1>
<h2>
<Link href="/">← Back to home</Link>
</h2>
</>
);
}
请注意,脚本组件中定义了几个其他属性:
- strategy控制应加载第三方脚本的时间。值 告诉 Next.js在浏览器空闲期间延迟加载此特定脚本lazyOnload
- onLoad用于在脚本完成加载后立即运行任何 JavaScript 代码。在此示例中,我们将一条消息记录到控制台,其中提到脚本已正确加载
尝试访问 http://localhost:3000/posts/first-post。由 使用浏览器的开发人员工具,您应该会在面板中看到上述消息。此外,您可以运行以查看脚本是否已填充此全局 变量。Consolewindow.FB
**注意:**Facebook SDK仅用作人为示例,以展示如何添加第三方 以高性能方式编写应用程序的脚本。现在您了解了包含的基础知识 Next.js 中的第三方功能,您可以从之前删除脚本组件 进行中。FirstPost
CSS 样式
现在让我们谈谈CSS样式。
如您所见,我们的索引页(http://localhost:3000)已经有一些样式。如果你看一下你的文件结构,你会看到一个文件夹,里面有两个CSS文件:一个全局样式表()和一个CSS模块()。stylesglobals.cssHome.module.css
如果您的项目没有这些文件,您可以在此处下载起始代码:
npx create-next-app nextjs-blog --use-npm --example "https://github.com/vercel/next-learn/tree/master/basics/assets-metadata-css-starter"
CSS 模块
CSS 模块允许您通过自动创建唯一的类名在组件级别本地限定 CSS 的作用域。这允许您在不同的文件中使用相同的 CSS 类名,而不必担心类名冲突。
除了 CSS 模块之外,您还可以通过多种方式设置 Next.js 应用程序的样式,包括:
- Sass,允许您导入和文件。.css.scss
- PostCSS库,如Tailwind CSS。
- CSS in-JS 库,如 styled-jsx、styled-components 和 emotion
在本课中,我们将在Next.js中讨论如何使用CSS模块和Sass。让我们潜入!
布局组件
首先,让我们创建一个将在所有页面之间共享的布局组件。
- 创建名为 的顶级目录。components
- 在 中,创建一个包含以下内容的文件:componentslayout.js
export default function Layout({ children }) {
return <div>{children}</div>;
}
然后,打开 ,为组件添加导入,并使其成为最外层的组件:pages/posts/first-post.jsLayout
import Head from 'next/head';
import Link from 'next/link';
import Layout from '../../components/layout';
export default function FirstPost() {
return (
<Layout>
<Head>
<title>First Post</title>
</Head>
<h1>First Post</h1>
<h2>
<Link href="/">← Back to home</Link>
</h2>
</Layout>
);
}
添加 CSS
现在,让我们向组件添加一些样式。为此,我们将使用 CSS 模块,它允许您在 React 组件中导入 CSS 文件。Layout
创建一个包含以下内容的调用文件:components/layout.module.css
.container {
max-width: 36rem;
padding: 0 1rem;
margin: 3rem auto 6rem;
}
**重要:**要使用 CSS 模块,CSS 文件名必须以 结尾。.module.css
要在 中使用此类,您需要:containercomponents/layout.js
- 导入 CSS 文件并为其指定名称,例如styles
- 用作styles.containerclassName
打开其内容并将其替换为以下内容:components/layout.js
import styles from './layout.module.css';
export default function Layout({ children }) {
return <div className={styles.container}>{children}</div>;
}
如果转到“现在 http://localhost:3000/posts/first-post”,您应该看到文本现在位于居中的容器中:
自动生成唯一的类名
现在,如果你看一下浏览器开发工具中的 HTML,你会注意到组件呈现的类名如下所示:divLayoutlayout_container__...
这就是CSS模块的作用:它自动生成唯一的类名。只要使用 CSS 模块,就不必担心类名冲突。
此外,Next.js的代码拆分功能也适用于CSS模块。它确保为每个页面加载最少量的 CSS。这会导致捆绑包大小更小。
CSS 模块在构建时从 JavaScript 捆绑包中提取,并生成由 Next.js 自动加载的文件。.css
全局样式
CSS 模块对于组件级样式很有用。但是,如果您希望每个页面都加载一些CSS,Next.js也支持此功能。
若要将全局 CSS 加载到应用程序,请创建一个包含以下内容的调用文件:pages/_app.js
export default function App({ Component, pageProps }) {
return <Component {...pageProps} />;
}
的默认导出是一个顶级 React 组件,它包装了应用程序中的所有页面。您可以使用此组件在页面之间导航时保持状态,或者像我们在这里所做的那样添加全局样式。详细了解_app.js文件。_app.js
重新启动开发服务器
**重要:**添加页面/_app.js时,需要重新启动开发服务器。按下停止服务器并运行:Ctrl + c
npm run dev
添加全局 CSS
在Next.js中,您可以通过从页面/_app.js导入全局 CSS 文件来添加全局 CSS 文件。您不能在其他任何位置导入全局 CSS。
全局 CSS 无法导入外部的原因是全局 CSS 会影响所有pages/_app.js元素在页面上。
如果要从主页导航到页面,则主页中的全局样式会无意中受到影响。/posts/first-post/posts/first-post
您可以将全局 CSS 文件放置在任何位置并使用任何名称。因此,让我们执行以下操作:
- 创建顶级目录和文件。stylesglobal.css
- 在 中添加以下 CSS。此代码重置某些样式并更改标记的颜色:styles/global.cssa
html, body { padding: 0; margin: 0; font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; line-height: 1.6; font-size: 18px; } * { box-sizing: border-box; } a { color: #0070f3; text-decoration: none; } a:hover { text-decoration: underline; } img { max-width: 100%; display: block; }
最后,将 CSS 文件导入到您之前创建的文件中:pages/_app.js
// pages/_app.js
import '../styles/global.css'; export default function App({ Component, pageProps }) { return <Component {...pageProps} />; }
现在,如果您访问 http://localhost:3000/posts/first-post,您将看到样式已应用。导入的任何样式都将全局应用于应用程序的所有页面。_app.js
如果不起作用:请确保在更新时重新启动开发服务器。pages/_app.js
美化布局
到目前为止,我们只添加了最少的 React 和 CSS 代码来说明 CSS 模块等概念。在我们继续下一课关于数据获取之前,让我们完善我们的页面样式和代码。
更新components/layout.module.css
首先,打开并用以下更精美的样式替换其内容,用于布局和个人资料图片:components/layout.module.css
.container {
max-width: 36rem;
padding: 0 1rem;
margin: 3rem auto 6rem;
}
.header {
display: flex;
flex-direction: column;
align-items: center;
}
.backToHome {
margin: 3rem 0 0;
}
创造styles/utils.module.css
其次,让我们创建一组可以在多个组件中重用的 CSS 实用程序类(用于文本样式)。
添加一个调用的新 CSS 文件,其中包含以下内容:styles/utils.module.css
.heading2Xl {
font-size: 2.5rem;
line-height: 1.2;
font-weight: 800;
letter-spacing: -0.05rem;
margin: 1rem 0;
}
.headingXl {
font-size: 2rem;
line-height: 1.3;
font-weight: 800;
letter-spacing: -0.05rem;
margin: 1rem 0;
}
.headingLg {
font-size: 1.5rem;
line-height: 1.4;
margin: 1rem 0;
}
.headingMd {
font-size: 1.2rem;
line-height: 1.5;
}
.borderCircle {
border-radius: 9999px;
}
.colorInherit {
color: inherit;
}
.padding1px {
padding-top: 1px;
}
.list {
list-style: none;
padding: 0;
margin: 0;
}
.listItem {
margin: 0 0 1.25rem;
}
.lightText {
color: #666;
}
您可以在整个应用程序中重用这些实用程序类,甚至可以在文件中使用实用程序类。实用程序类是指编写CSS选择器而不是方法的方法(例如全局样式,CSS模块,Sass等)。详细了解实用工具优先的 CSS。global.css
更新components/layout.js
第三,打开并用以下代码替换其内容,更改为实际名称:components/layout.jsYour Name
import Head from 'next/head';
import Image from 'next/image';
import styles from './layout.module.css';
import utilStyles from '../styles/utils.module.css';
import Link from 'next/link';
const name = 'Your Name';
export const siteTitle = 'Next.js Sample Website';
export default function Layout({ children, home }) {
return (
<div className={styles.container}>
<Head>
<link rel="icon" href="/favicon.ico" />
<meta
name="description"
content="Learn how to build a personal website using Next.js"
/>
<meta
property="og:image"
content={`https://og-image.vercel.app/${encodeURI(
siteTitle,
)}.png?theme=light&md=0&fontSize=75px&images=https%3A%2F%2Fassets.vercel.com%2Fimage%2Fupload%2Ffront%2Fassets%2Fdesign%2Fnextjs-black-logo.svg`}
/>
<meta name="og:title" content={siteTitle} />
<meta name="twitter:card" content="summary_large_image" />
</Head>
<header className={styles.header}>
{home ? (
<>
<Image
priority
src="/images/profile.jpg"
className={utilStyles.borderCircle}
height={144}
width={144}
alt=""
/>
<h1 className={utilStyles.heading2Xl}>{name}</h1>
</>
) : (
<>
<Link href="/">
<Image
priority
src="/images/profile.jpg"
className={utilStyles.borderCircle}
height={108}
width={108}
alt=""
/>
</Link>
<h2 className={utilStyles.headingLg}>
<Link href="/" className={utilStyles.colorInherit}>
{name}
</Link>
</h2>
</>
)}
</header>
<main>{children}</main>
{!home && (
<div className={styles.backToHome}>
<Link href="/">← Back to home</Link>
</div>
)}
</div>
);
}
以下是新增功能:
- 元标记(如),用于描述页面内容og:image
- 布尔道具,将调整标题和图像的大小home
- 底部的“返回主页”链接,如果是homefalse
- 添加了带有 的图像,这些图像预加载了优先级属性next/image
更新pages/index.js
最后,让我们更新主页。
打开其内容并将其替换为:pages/index.js
import Head from 'next/head';
import Layout, { siteTitle } from '../components/layout';
import utilStyles from '../styles/utils.module.css';
export default function Home() {
return (
<Layout home>
<Head>
<title>{siteTitle}</title>
</Head>
<section className={utilStyles.headingMd}>
<p>[Your Self Introduction]</p>
<p>
(This is a sample website - you’ll be building a site like this on{' '}
<a href="https://nextjs.org/learn">our Next.js tutorial</a>.)
</p>
</section>
</Layout>
);
}
然后用你的自我介绍代替。以下是作者个人资料的示例:[Your Self Introduction]
就是这样!我们现在有了完善的布局代码,我们准备继续我们的数据获取课程。
在结束本课程之前,让我们在下一页讨论一些与Next.js的CSS支持相关的有用技术。
Styling Tips
以下是一些可能会有所帮助的样式提示。
您可以通读以下部分。无需更改我们的应用程序!
使用库切换类clsx
CLSX 是一个简单的库,可让您轻松切换类名。您可以使用 或 进行安装。npm install clsxyarn add clsx
请查看其文档以获取更多详细信息,但以下是基本用法:
- 假设您要创建一个接受 的组件,该组件可以是 或 。Alerttype'success''error'
- 如果是 ,则希望文本颜色为绿色。如果是 ,则希望文本颜色为红色。'success''error'
你可以先写一个CSS模块(例如),像这样:alert.module.css
.success {
color: green;
}
.error {
color: red;
}
并像这样使用:clsx
import styles from './alert.module.css';
import { clsx } from 'clsx';
export default function Alert({ children, type }) {
return (
<div
className={clsx({
[styles.success]: type === 'success',
[styles.error]: type === 'error',
})}
>
{children}
</div>
);
}
自定义 PostCSS 配置
开箱即用,无需配置,Next.js 使用 PostCSS 编译 CSS。
要自定义PostCSS配置,您可以创建一个名为postcss.config.js的顶级文件。如果您使用的是 Tailwind CSS 等库,这将非常有用。
以下是添加 Tailwind CSS 的步骤。首先,安装软件包:
npm install -D tailwindcss autoprefixer postcss
然后,创建一个 postcss.config.js:
// postcss.config.js
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};
我们还建议通过指定以下选项来配置内容源:contenttailwind.config.js
// tailwind.config.js
module.exports = {
content: [
'./pages/**/*.{js,ts,jsx,tsx}',
'./components/**/*.{js,ts,jsx,tsx}',
// For the best performance and to avoid false positives,
// be as specific as possible with your content configuration.
],
};
要了解有关自定义 PostCSS 配置的更多信息,请查看 PostCSS 的文档。
要轻松开始使用 Tailwind CSS,请查看我们的示例。
使用Sass
开箱即用的 Next.js 允许您同时使用 和 扩展导入 Sass。您可以通过 CSS 模块和 or 扩展使用组件级 Sass。.scss.sass.module.scss.module.sass
在使用 Next.js 的内置 Sass 支持之前,请务必安装 sass:
npm install -D sass
本课就讲到这里!
要了解有关Next.js内置CSS支持和CSS模块的更多信息,请查看CSS文档。
2023.2.16 4:07 记录