Next.js超简洁完整篇

Next.js超简洁完整篇

1、Next.js认识

👉 官方网站

js 复制代码
// Next.js官网
https://nextjs.org/

// Next.js 中文网
https://next.nodejs.cn/

👉先来看看我们环境要求

js 复制代码
系统环境需求
Node.js 12.22.0 或更高版本
MacOS、Windows (包括 WSL) 和 Linux 都被支持

这里我本地使用的依然是node20.12.0

👉Next.js是什么

Next.js 是一个基于 React 的轻量级框架,提供了服务器端渲染(SSR)、静态站点生成(SSG)、API 路由

也就是说对应的就是Nuxt(Vue全家桶系列),而Next.js算是React与之对应的

👉Next.js优点

服务器端渲染(SSR)

Next.js 支持将页面预渲染为 HTML,在服务器端发送到浏览器。提高页面加载和 SEO

静态站点生成(SSG)

在构建时我们可以生成静态 HTML 文件,加快站点的加载速度

API 路由

在 Next.js 中API 路由能让我们在一个项目中实现前端和后端的功能

代码拆分

Next.js 会为每个页面进行代码拆分,仅加载当前页面需要的 JavaScript,提升性能。

文件系统路由

Next.js 使用文件系统作为路由机制

支持 TypeScript 和 CSS-in-JS

Next.js 内置对 TypeScript 和 CSS-in-JS(如 styled-components)的支持。

2、Next项目安装创建

👉环境要求

Node.js 18.17或更高版本。

js 复制代码
`https://nodejs.cn/` 

支持 macOS、Windows(包括 WSL)和 Linux。

👉搭建运行

js 复制代码
npx create-next-app@latest
  
# or

yarn create next-app@latest xxx

npx create-next-app@latest nexusnext (这里我采用的构建方式)

安装时看到以下提示:

js 复制代码
Need to install the following packages:
[email protected]
Ok to proceed? (y) y

// 选择y 就是需要装一些东西

// 下面 是我选择的部分
Ok to proceed? (y) y
√ Would you like to use TypeScript? ... No / Yes    //Yes采用
√ Would you like to use ESLint? ... No / Yes  // No未采用
√ Would you like to use Tailwind CSS? ... No / Yes  //Yes采用
√ Would you like your code inside a `src/` directory? ... No / Yes //Yes采用
√ Would you like to use App Router? (recommended) ... No / Yes //Yes采用
√ Would you like to use Turbopack for `next dev`? ... No / Yes //Yes采用
√ Would you like to customize the import alias (`@/*` by default)? ... No / Yes //Yes采用
√ What import alias would you like configured? ... @/* //Yes采用

3、运行项目

这个时候我们已经安装好了依赖了,就可以进行启动了

js 复制代码
yarn dev

这个时候我们的项目已经启动了

4、打包部署

Next.js给我们提供了四种方式的部署

Deployment Option Feature Support
Node.js server All
Docker container All
Static export Limited
Adapters Platform-specific

接下来我们就尝试最简单直接的静态部署

我们打包到github pages进行静态托管

👉 设置静态部署方式

next.config.mjs中只需要将output 方式设置为静态模式

js 复制代码
/** @type {import('next').NextConfig} */
const nextConfig = {
  output: 'export',
};
export default nextConfig;

👉指定静态文件输出目录

next.config.js=> nextConfig=> distDir

js 复制代码
/** @type {import('next').NextConfig} */
const nextConfig = {
  distDir: 'out', // 指定静态文件输出目录为 out
  output: 'export',
};
export default nextConfig;

👉 打包

js 复制代码
yarn build

打包以后文件结构如图

👉预览本地打包的静态文件

js 复制代码
// 安装http-server
npm install -g http-server



//进入打包目录启动本地 HTTP 服务器
cd out

http-server -p 3000

接下来就可以点击提示我们生成的地址查看项目了,也可以将根目录=> out目录下面的文件部署到任何地方

js 复制代码
http://127.0.0.1:3000

5、Next.js结构搭建

👉默认目录

Next.js 使用文件系统路由,这意味着应用中的路由由你构建文件的方式决定

默认的时候已经帮我们创建了 app/ 文件夹,添加了 layout.tsxpage.tsx 文件

当用户访问应用的根目录 (/) 时,将渲染这些内容

🍎 app下面目录结构以及代表的含义
js 复制代码
布局(layout.js)
模板(template.js)
加载状态(loading.js)
错误处理(error.js)
404(not-found.js)

//目录以及代表的含义
pages/:这个目录用于存放页面组件。每个文件都会自动成为一个路由。
public/:这个目录用于存放静态文件,如图片、字体等。
styles/:这个目录用于存放样式文件。
components/:这个目录用于存放可复用的组件
🍎搭建常见的目录结构

src下面新建文件夹以及结构如下

js 复制代码
my-next-ts-project/
│
├── public/                   # 公共文件夹(放置静态资源)
│   ├── images/               # 图片资源
│   ├── favicon.ico           # 网站图标
│   └── robots.txt            # 机器人文件,控制爬虫抓取规则
│
├── src/                      # 源代码
│   ├── assets/               # 静态资源(如图片、字体等)
│   ├── components/           # 组件(按功能划分的可复用组件)
│   ├── pages/                # 页面(每个文件对应一个路由)
│   │   ├── _app.tsx          # 自定义的 App 组件,用于页面的初始化
│   │   ├── _document.tsx     # 自定义文档(如果有需要)
│   │   ├── index.tsx         # 首页(默认路由)
│   │   ├── about.tsx         # 关于页面
│   │   └── contact.tsx       # 联系页面
│   ├── styles/               # 样式文件(CSS, SASS, 或 CSS 模块)
│   │   ├── globals.css       # 全局样式
│   │   └── Home.module.css   # 主页特有样式(可以是 CSS 模块)
│   ├── utils/                # 工具函数(帮助类文件)
│   ├── services/             # API 服务(与后端接口相关的文件)
│   ├── hooks/                # 自定义 React hooks
│   ├── contexts/             # React context 管理
│   └── config/               # 配置文件(例如环境变量、项目配置)
│
├── .env                      # 环境变量配置
├── .gitignore                # Git 忽略文件
├── next-env.d.ts             # TypeScript 环境类型文件
├── next.config.js            # Next.js 配置文件
├── package.json              # 项目信息和依赖
├── tsconfig.json             # TypeScript 配置文件
└── README.md                 # 项目说明文件

👉配置next.config.ts根目录

next.config.ts=> NextConfig=> srcDir

配置以后我们的根目录就是src目录了

js 复制代码
import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  /* config options here */
  srcDir: 'src', // 指定源码目录为 src
  distDir: 'dist', // 指定静态文件输出目录为 out
  output: 'export',
};
export default nextConfig;

👉首页搭建

next默认的首页就是 pages/page.tsx,默认的pages/page.tsx如下图

🍎layout.tsx

js版本的时候

js 复制代码
export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  )
}

写成ts

js 复制代码
export default function RootLayout({children}: {children: React.ReactNode}) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  )
}

配置项目跟目录src在 next.config.ts之中以后

🍎首页内容pages=> index.tsx

这个就是我们的首页

js 复制代码
// src/app/page.tsx
import React from 'react';
import Header from '../components/Header';
import Footer from '../components/Footer';

const Home: React.FC = () => {
  return (
    <div>
      <Header />
      <main style={{ padding: '40px', textAlign: 'center' }}>
        <h1>Welcome to My Website</h1>
        <p>This is the homepage of our awesome website!</p>
      </main>
      <Footer />
    </div>
  );
};

export default Home;
🍎头部Footer.tsx
js 复制代码
// src/components/Footer.tsx
import React from 'react';

const Footer: React.FC = () => {
  return (
    <footer style={{ marginTop: '40px', padding: '20px', backgroundColor: '#222', color: 'white' }}>
      <p>&copy; 2025 My Website. All Rights Reserved.</p>
    </footer>
  );
};

export default Footer;
🍎底部Header.tsx
js 复制代码
// src/components/Header.tsx
import React from 'react';

const Header: React.FC = () => {
  return (
    <header>
      <nav>
        <ul style={{ listStyleType: 'none', display: 'flex', gap: '20px' }}>
          <li><a href="/">Home</a></li>
          <li><a href="/about">About</a></li>
          <li><a href="/services">Services</a></li>
          <li><a href="/contact">Contact</a></li>
        </ul>
      </nav>
    </header>
  );
};

export default Header;

搭建以后初步预览

接下来我们就可以继续完善我们的项目

6、Next.js 路由

👉搭建二级目录以及多级目录

我们新建目录和文件如下图所示:

js 复制代码
src\app\about
  src\app\about\contact.tsx  //联系我们
  src\app\about\service.tsx  //服务我们

我们想有个关于我们,里面有个联系我们和服务我们,这两个页面均使用about下的公共组件,如何实现呢?

建立如下图的文件路径

js 复制代码
src\app
    \about
    layout.tsx //控制访问about下的公共组件
    page.tsx  //控制访问about显示
      \about\services\page.tsx  //控制访问about=>services显示
      \about\contact\page.tsx  //控制访问about=>contact显示
🍎 默认页面(page.tsx)

page.tsx为我们默认的页面,访问目录的时候一般就直接访问这个里面的内容

js 复制代码
// pages/about/index.tsx
import React from 'react';
const About: React.FC = () => {
  return (
    <div>
      <h1>关于我们</h1>
      <p>这里是关于我们的页面内容。</p>
    </div>
  );
};

export default About;
🍎 定义布局(layout.tsx)

布局是指多个页面共享的 UI。在导航的时候,布局会保留状态,保持可交互性并且不会重新渲染,比如用来实现后台管理系统的侧边导航栏。

定义一个布局,Next.js默认给我们每个文件下一个 layout.js的文件可以存放当前目录的公共组件部分,该文件默认导出一个 React 组件,该组件应接收一个 children prop,chidren 表示子布局(如果有的话)或者子页面。

js 复制代码
// pages/about/Layout.tsx
import React from 'react';
interface AboutLayoutProps {
  children: React.ReactNode;
}
const AboutLayout: React.FC<AboutLayoutProps> = ({ children }) => {
  return (
    <div>
      我是about的一级
      <main style={{ padding: '40px', textAlign: 'center' }}>
        {children}
      </main>
    </div>
  );
};

export default AboutLayout;
🍎 二级子菜单

内容位于\about\services\page.tsx

js 复制代码
export default function Service() {
  return (
    <div>我是关于about=》服务</div>
  )
}

通过这种方式我们就可以达到无限控制二级菜单以及更多子级菜单的效果

👉路由跳转

在Next之中我们如何跳转路由呢

🍎Link跳转

js 复制代码
//引入
import Link from 'next/link'

//使用
<li><a href="/about">About</a></li>

🍎动态路由

我们也可拼接动态路由来展示我们的内容部分

js 复制代码
// 动态路由

<Link href="/post/[id]" as={`/post/${post.id}`}>
  <a>{post.title}</a>
</Link>

7、Next.js 主题以及配置

👉使用不同的主题

这里很简单,假如我们采用自定义样式的方式,只需要更改主题最顶部的data-theme名称即可

js 复制代码
'use client'
import Image from "next/image";
import React, { useEffect, useState } from 'react';
export default function Home() {
  const [theme, setTheme] = useState<'light' | 'dark' | 'default'>('default'); // 'light' or 'dark'

  useEffect(() => {
    // 根据 theme 状态切换 data-theme
    document.documentElement.setAttribute('data-theme', theme);
  }, [theme]);

  return (
    <div>
      <main style={{ padding: '40px', textAlign: 'center' }}>
        <button onClick={() => setTheme('default')}>
          Toggle Theme
        </button>
        <button onClick={() => setTheme('dark')}>
          Toggle Theme
        </button>
        <button onClick={() => setTheme('light')}>
          Toggle Theme
        </button>
      </main>
    </div>
  );
}

添加以后我们最顶部就成为了下面这样子

js 复制代码
<html lang="en" data-theme="light">

然后针对不同的主题做样式

js 复制代码
/* 默认主题 */
[data-theme='default'] {
  --theme-color:#7F78FF; /* 默认主题 */
  --primary-color: #2c3e50; /* 深色主题的主色 */
  --secondary-color: #1abc9c; /* 深色主题的次色 */
}
/* 主题切换:深色主题 */
[data-theme='dark'] {
  --primary-color: #2c3e50; /* 深色主题的主色 */
  --secondary-color: #1abc9c; /* 深色主题的次色 */
}

/* 主题切换:浅色主题 */
[data-theme='light'] {
  --primary-color: #3498db; /* 浅色主题的主色 */
  --secondary-color: #2ecc71; /* 浅色主题的次色 */
}

使用这个主题定义的颜色

js 复制代码

👉 使用客户端

在next之中我们使用的服务端渲染,如果需要使用一些客户端的hooks,需要在顶部添加识别即可

js 复制代码
'use client'

8、部署上线

👉部署github pages

🍎修改next.config.ts 文件
js 复制代码
import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  distDir: 'dist', // 指定静态文件输出目录为 out
  output: 'export',
  basePath: '/nexus',  // 替换为你的 GitHub 仓库名
  assetPrefix: '/nexus/',  // 替换为你的 GitHub 仓库名
};
export default nextConfig;
🍎安装部署需要的依赖
js 复制代码
安装 GitHub Pages 依赖
为了将构建的静态文件部署到 GitHub Pages,你需要安装 gh-pages 包:

npm install gh-pages --save-dev

yarn add gh-pages --save-dev
🍎在 package.json 中添加脚本

需要注意next export已经移除了

js 复制代码
 "scripts": {
    "dev": "next dev --turbopack",
    "build": "next build",
    "start": "next start",
    "lint": "next lint",
    // "predeploy": "next build && next export",  错误 删掉 已经移除next export
    "deploy": "gh-pages -d dist"
  },
🍎 打包部署
js 复制代码
yarn build
yarn deploy

这个时候我们项目已经成功部署了,访问远程即可操作我们的仓库了

报错提示

👉 children规定类型报错

js 复制代码
./src/app/admin/layout.tsx:13:3
Type error: Binding element 'children' implicitly has an 'any' type.

  11 |
  12 | export default function DashboardLayout({
> 13 |   children,
     |   ^
  14 | }) {
  15 |   const pathname = usePathname();
  16 |   console.log(pathname,'Nav-地址');
error Command failed with exit code 1.
原因

主要是children类型为any报错

解决方法

进行约束即可

js 复制代码
// 旧的写法
export default function DashboardLayout({
  children,
}) {

  //新的约束写法 
export default function DashboardLayout({
  children,
}: {children: React.ReactNode}) {}
相关推荐
蓝胖子的多啦A梦11 分钟前
搭建前端项目 Vue+element UI引入 步骤 (超详细)
前端·vue.js·ui
TE-茶叶蛋13 分钟前
WebSocket 前端断连原因与检测方法
前端·websocket·网络协议
骆驼Lara22 分钟前
前端跨域解决方案(1):什么是跨域?
前端·javascript
离岸听风25 分钟前
学生端前端用户操作手册
前端
onebyte8bits27 分钟前
CSS Houdini 解锁前端动画的下一个时代!
前端·javascript·css·html·houdini
yxc_inspire32 分钟前
基于Qt的app开发第十四天
前端·c++·qt·app·面向对象·qss
一_个前端39 分钟前
Konva 获取鼠标在画布中的位置通用方法
前端
程序员爱钓鱼1 小时前
Go同步原语与数据竞争:原子操作(atomic)
后端·面试·go
天天摸鱼的java工程师1 小时前
Kafka是如何保证消息队列中的消息不丢失、不重复?
java·后端·kafka
天天摸鱼的java工程师1 小时前
SpringBoot 自动配置原理?@EnableAutoConfiguration 是如何工作的?
java·后端