# Next.js 入门学习教程
# 准备工作
- [✓] 一台 MacBook
- [✓] 编辑器:VSCode
- [✓] 终端:iterm2+zsh
- [✓] 环境:Nodejs、科学上网
Next.js 是一个基于 Node.js 的框架,所以首先需要安装 Node.js。你可以从 Node.js 官方网站 (opens new window) 下载并安装最新版本。
# 创建项目
项目文件夹名 my-nextjs-app
npx create-next-app my-nextjs-app
为了更容易理解Next.js,你可以所有选项都选 No
进入my-nextjs-app
cd my-nextjs-app
运行开发模式
npm run dev
打开浏览器,访问 http://localhost:3000 (opens new window),你将看到一个基本的 Next.js 应用程序正在运行。
# 基础概念
# 页面 & 路由
pages文件夹的意义是我们所有页面的存放地点, 当我们访问根目录(/)时,会自动找到/index.js,同理访问(/new),则会找到/pages/new.js
/pages/index.js 内容比较多,为了方便理解,我们先不去修改它。
我们新建一个list.js在pages文件夹下
// pages/list.js
import Link from 'next/link';
const projects = [
{ id: 1, title: '点我跳转' },
];
const List = () => {
return (
<div>
<h1>Project List</h1>
<div>页面跳转传参: /detail/[id]</div>
<ul>
{projects.map((project) => (
<li key={project.id}>
<Link target="_blank" href={`/detail/${project.id}`}>
{project.title}
</Link>
</li>
))}
</ul>
<div>页面跳转传参: /detail?id=[id]</div>
<ul>
{projects.map((project) => (
<li key={project.id}>
<Link target="_blank" href={`/detail?id=${project.id}`}>
{project.title}
</Link>
</li>
))}
</ul>
<div>页面跳转传参: /detail/[id]/view</div>
<ul>
{projects.map((project) => (
<li key={project.id}>
<Link target="_blank" href={`/detail/${project.id}/view`}>
{project.title}
</Link>
</li>
))}
</ul>
</div>
);
};
export default List;
为了页面清爽一点 找到 _app.js
我们先把样式引入注释掉
// import '@/styles/globals.css'
export default function App({ Component, pageProps }) {
return <Component {...pageProps} />
}
现在我们 访问 http://localhost:3000/list (opens new window) ,可以看到我们刚刚创建的页面。
可以看到我们列举了3种页面传参的方式,下面我们演示如何接收参数
# 接收方式1
在pages文件夹下创建detail文件夹,在detail文件夹下创建一个文件名为 [id].js
的文件
//目录结构
pages/
├── detail/
│ └── [id].js
// pages/detail/[id].js
import { useRouter } from 'next/router';
const Detail = () => {
const router = useRouter();
const { id } = router.query; // 从路由参数中获取项目的ID
return (
<div>
<h1>Project Details</h1>
<p>Project ID: {id}</p>
</div>
);
};
export default Detail;
访问 http://localhost:3000/detail/1 (opens new window) 即可看到页面已经呈现,参数也被接收
# 接收方式2
在pages文件夹下创建一个文件名为 detail.js
的文件
//目录结构
pages/
├── detail.js
// pages/detail.js
import { useRouter } from 'next/router';
const Detail = () => {
const router = useRouter();
const { id } = router.query; // 从路由参数中获取项目的ID
return (
<div>
<h1>Project Details</h1>
<p>Project ID: {id}</p>
</div>
);
};
export default Detail;
访问 http://localhost:3000/detail?id=1 (opens new window) 即可看到页面已经呈现,参数也被接收
# 接收方式3
在pages文件夹下创建detail文件夹,在detail文件夹下创建一个文件名为 [id].js
的文件
//目录结构
pages/
├── detail/
│ └── [id]/
│ └── view.js
// pages/detail/[id]/view.js
import { useRouter } from 'next/router';
const Detail = () => {
const router = useRouter();
const { id } = router.query; // 从路由参数中获取项目的ID
return (
<div>
<h1>Project Details</h1>
<p>Project ID: {id}</p>
</div>
);
};
export default Detail;
访问 http://localhost:3000/detail/1/view (opens new window) 即可看到页面已经呈现,参数也被接收
# 数据获取
其中两个重要的函数 getServerSideProps
和 getStaticProps
来获取数据并在服务器端预取数据,以便在渲染页面时使用。
# getServerSideProps:
用于在每次请求页面时获取数据。 在服务器端运行,因此可以执行任何服务器端代码,例如调用数据库、访问外部 API 等。 每次请求页面时都会运行 getServerSideProps 函数,因此数据是实时获取的。 返回的数据将作为页面组件的 props,在服务器端渲染时使用。 适用于需要根据每个请求动态获取数据的场景,例如个性化页面、需要实时数据更新的页面等。
# getStaticProps:
用于在构建时(而不是每次请求)获取数据。 在构建时运行,因此它不能包含任何服务器端代码。 可以访问远程数据源或文件系统,并将数据预先获取到静态页面中。 返回的数据将作为页面组件的 props,在静态页面渲染时使用。 适用于静态数据或不经常更改的数据,例如博客文章、产品列表等。
下面我以getServerSideProps
为例,做一个天气页面,创建文件 /pages/weather.js
//目录结构
pages/
├── weather.js
// pages/weather.js
function WeatherPage({ weatherData }) {
// 使用从 getServerSideProps 获取的天气数据渲染页面
return (
<div>
<h1>{weatherData.cityInfo.city}</h1>
<p>当前温度:{weatherData.data.wendu}℃</p>
<p>天气状况:{weatherData.data.forecast[0].type}</p>
</div>
);
}
//在getServerSideProps里请求的接口地址是不会被别人看到的
export async function getServerSideProps() {
// 在这里执行异步操作,从天气API获取数据
const response = await fetch('http://t.weather.sojson.com/api/weather/city/101010100');
const data = await response.json();
// 返回获取的天气数据作为 props
return {
props: {
weatherData: data,
},
};
}
export default WeatherPage;
访问 http://localhost:3000/weather (opens new window) 即可看到页面已经出现实时天气
你可以在getServerSideProps
里做任何数据处理,比如查询SQL,请求外部API等。
# 部署
# 部署在Vercel
# 项目在本地
我们需要在本地安装 vercel,建议是全局安装:
npm install -g vercel
之后执行如下命令保证你本地登录了 vercel 账号:
vercel login
之后进入你的项目根路径,执行 vercel 即可:
vercel
# 项目在Github
打开 https://vercel.com/dashboard
点击 Add New...
点击 Project
,Import
你的项目即可;
# 部署在自己的服务器
首先我们在package.json
里增加一行prod
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"prod": "next build && next start",
"lint": "next lint"
},
我们以宝塔面板
为例
- 打开宝塔面板 -> 网站 -> Node项目 -> 添加Node项目
- 启动选项:prod
- 项目端口:3000
如果你想换一个端口,那么你需要将上面的prod 改成 例如
next build && next start -p 3001
即可,绑定域名可以更方便的访问
# 结语
Next.js的学习当然没有这么简单,例如还有中间件
管理样式
插件和库
自定义组件
docker部署
持续集成
,以及我们在在最初创建项目时,所有选择的No
,改成Yes
,会有什么样的变化呢?
更全面的教学文档,请查看Next.js官方提供的文档 https://nextjs.org/docs (opens new window)