*基于 next.js 官方文档的学习笔记
环境
Node.js >= 10.13
创建
js创建:
npx create-next-app@latest
# or
yarn create next-app
# or
pnpm create next-app
ts创建:
npx create-next-app@latest --typescript
# or
yarn create next-app --typescript
# or
pnpm create next-app --typescript
页面间导航
pages目录
目录中的pages,里面的目录名就决定了它的路由
pages/index.js路由就是/.pages/posts/first-post.js路由就是/posts/first-post.
也就是你不需要自己去配置路由,pages中的目录结构就是路由了
Link组件
用法: 头部引入
import Link from 'next/link';
使用:
<h1 className="title">
Read <Link href="/posts/first-post">this page!</Link>
</h1>
跟 <a> 长的一样
<Link> 跟 <a> 不同,它是以客户端导航的形式在两个页面间跳转,而不是加载整个页面
在html中添加背景颜色,切换页面会保持背景颜色 像这样:
好像就是单页面应用的意思
而且next还是按需加载的,页面访问到才会去加载
资源、元数据和CSS样式
资源
Image组件
可以理解为比Img优化更好和兼容性更好
默认懒加载
SEO:图像总是以避免累积布局变化的方式渲染,这是Google将在搜索排名中使用的核心Web至关重要。
使用:
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"
/>
);
元数据
Head组件
用来修改像 <title> 一样在 <head> 中的html标签
使用:
import Head from 'next/head';
<Head>
<title>Create Next App</title>
<link rel="icon" href="/favicon.ico" />
</Head>
Script组件
用原来这种方法引入第三方库会有阻塞问题
<Head>
<title>First Post</title>
<script src="https://connect.facebook.net/en_US/sdk.js" />
</Head>
使用:
import Script from 'next/script';
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="/">
<a>Back to home</a>
</Link>
</h2>
</>
);
}
Script组件中已经定义了一些其他属性:
strategy:控制第三方脚本应什么时候加载。lazyOnload的值告诉Next.js在脚本不需要用到的时候 慢加载。
onLoad:脚本完成加载后,使用Onload将立即运行任何JavaScript代码。在此示例中,我们将消息记录打印到控制台,提到脚本已正确加载
CSS样式
局部样式
创建module.css后缀名文件
.container {
max-width: 36rem;
padding: 0 1rem;
margin: 3rem auto 6rem;
}
使用import导入并使用:
import styles from './layout.module.css';
export default function Layout({ children }) {
return <div className={styles.container}>{children}</div>;
}
如果打印styles会发现是一个对象 长这样
生成html长这样
所以module.css的作用就是自动生成独特的类名来创建一个作用域,防止样式冲突
全局样式
全局样式一般放在
然后在 pages/_app.js 文件中引入
因为 _app.js 是所有组件的根组件,所以在此引入的样式全局生效
使用:
// `pages/_app.js`
import '../styles/global.css';
export default function App({ Component, pageProps }) {
return <Component {...pageProps} />;
}
番外篇
classnames库切换样式
PostCSS Config的使用来支持像Tailwind CSS一样的库
Sass的使用
教程访问: Styling Tips - Assets, Metadata, and CSS | Learn Next.js (nextjs.org)
预渲染和数据获取
预渲染(Pre-rendering)
Next.js 在服务端预渲染每一个页面,生成HTML给客户端,不需要通过客户端JavaScript完成所有操作
这样客户端的资源消耗少,且预渲染的页面满足 SEO
可以通过关闭 Chrome 的 JavaScript 来测试 Next.js 的预渲染
Pre-rendering - Pre-rendering and Data Fetching | Learn Next.js (nextjs.org)
预渲染有两种形式:
静态生成 SSG (Static Generation):
打包的时候生成HTML给客户端,之后每一个请求都复用同一个HTML
服务端渲染 SSR (Server-side Rendering):
每一个请求服务端都要生成HTML
每一个页面都可以选择要 SSG 还是 SSR,你可以选择大部分页面使用 SSG 小部分使用 SSR
尽量使用 SSG ,因为页面只需生成一次,之后由 CDN 提供
SSG应用场景
- 营销页面
- 博客文章
- 电子商务产品列表
- 帮助和文档
如果您不能在用户的请求之前预渲染页面,那么静态生成不是一个好选择。又或者页面需要经常更新显示的数据,并且在每个请求都会更改页面内容。
那么就需要SSR,虽然慢一些,但是预渲染页面会保持最新状态,或者你直接用客户端渲染。
静态生成 (SSG)
静态生成又分为 依赖数据的 和 不依赖数据的
不依赖数据的就是一般的静态页面,直接打包发出去就完事了
但依赖数据的需要在打包的时候取得外部数据(如文件数据,接口数据,数据库数据)来渲染页面
依赖数据的静态生成
用 getStaticProps()
它是如何工作的?在Next.js中,当你导出页面组件时,你还可以导出 getStaticProps 的异步函数。
getStaticProps会在打包的时候被调用- 在函数内部,您可以获取外部数据并将其作为 props 传到页面函数作为参数。
export default function Home(props) { ... }
export async function getStaticProps() {
// Get external data from the file system, API, DB, etc.
const data = ...
// The value of the `props` key will be
// passed to the `Home` component
return {
props: ...
}
}
关于文件数据的取用,与getStaticProps的使用
Creating a simple blog architecture - Pre-rendering and Data Fetching | Learn Next.js (nextjs.org)
服务端渲染 (SSG)
SSG 用 getServerSideProps
export async function getServerSideProps(context) {
return {
props: {
// props for your component
},
};
}
因为 getServerSideProps 会在请求时调用,所以参数 context 放的就是请求参数
只有需要在请求时必须获取数据的页面,才应使用 getServerSideProps。首字节时间(TTFB)比 getStaticProps 要慢,因为服务器必须对每个请求计算结果,并且在没有额外配置的情况下,CDN无法缓存结果。
客户端渲染介绍 和 SWR (React Hooks)
Fetching Data at Request Time - Pre-rendering and Data Fetching | Learn Next.js (nextjs.org)
动态路由
创建一个 [id].js 的文件 , 这就是一个动态路由组件
按常规声明组件,导出一个名为getstaticpaths的异步函数。在此函数中,我们需要返回ID的可能值列表。
import Layout from '../../components/layout';
export default function Post() {
return <Layout>...</Layout>;
}
export async function getStaticPaths() {
// Return a list of possible value for id
}
然后我们需要再次用到getStaticProps,函数会传入一个params包含了id,因为文件名叫 [id].js
import Layout from '../../components/layout';
export default function Post() {
return <Layout>...</Layout>;
}
export async function getStaticPaths() {
// Return a list of possible value for id
}
export async function getStaticProps({ params }) {
// Fetch necessary data for the blog post using params.id
}
总结图:
开发模式:getStaticPath 每次请求都会调用 生产模式:只在打包的时候调用
使用: Implement getStaticPaths - Dynamic Routes | Learn Next.js (nextjs.org)