Nextjs使用教程

2024-06-04 23:28
文章标签 使用 教程 nextjs

本文主要是介绍Nextjs使用教程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一.手动创建项目

建议看这个中文网站文档,这个里面的案例配置都是手动的,也可以往下看我这个博客一步步操作
1.在目录下执行下面命令,初始化package.json文件

npm init -y

2.安装react相关包以及next包

yarn add next react react-dom
// 或者
npm install --save next react react-dom

3.在package.json文件的script节点,新增以下内容

  "scripts": {...,"dev": "next",  // 开发时运行"build": "next build", // 打包时运行"start": "next start"  // 打完包启动服务的命令}

注意:Next.js 只支持React 16及以上

4.根目录下新建pages目录(这里面就是所有页面代码了,会根据这个目录的内容自动生成路由)

5.在pages里面新建index.js,放入以下内容进行测试

export default function(){return <div>我是pages/index下面的内容</div>
}

6.启动项目测试

npm run dev
// 或者
yarn run dev

7.访问控制台的local地址,显示出如下页面

在这里插入图片描述
8.打包

npm run build
// 或者
yarn run build

打完包会在项目下新建生成一个.next文件,在根目录下执行如下命令会和开发时看到的效果一致

npm run start
// 或者
yarn run start

二.快速创建项目

官网文档

执行下面创建项目的命令

npx create-next-app next-create

下面会出现一堆询问的配置信息,这里直接走默认就好了

定义路由

这里的页面都是统一放到app文件夹下面每个文件的page.js文件

例如直接访问localhost:3000则访问的是app/page.js文件

例如直接访问localhost:3000/user则访问的是app/user/page.js文件

export default function(){// className={"text-red-500"} 使用原子化css标签return <div className={"text-red-500"}>我是user/page文件</div>
}

如果访问的页面有很多网格效果,则去app/globals.css里面把样式都删除,只留前三行即可

页面与布局

将app/Layout.js进行改造

import { Inter } from "next/font/google";
import "./globals.css";const inter = Inter({ subsets: ["latin"] });export const metadata = {title: "Create Next App",  // 网站标题description: "Generated by create next app", // 描述信息
};export default function RootLayout({ children }) {return (<html lang="en"><body className={inter.className}>app下面的layout{children}</body></html>);
}

新建app/user/Layout.js存入以下内容

export default function userLayout({ children }) {return (<section>user下面的layout{children}</section>);
}

访问localhost:3000

在这里插入图片描述
访问localhost:3000/user

在这里插入图片描述
通过对比可以发现,app下面的就是公共的根样式,下面每个Layout.js都会继承到,然后每个文件夹下都可以定义当前路由页面的样式

链接和导航

修改下app/page.js内容如下

'use client';
import Link from "next/link";
import { useRouter } from "next/navigation";export default function Home() {const router = useRouter()return (<><h1 className="text-4xl text-orange-600">Hello Name</h1><br></br><Link href={"/user"}>跳转到user路由</Link><br></br><button onClick={()=>{router.push('/user')}}>点击跳转/user</button></>);
}

滚动到新路由的指定位置处,相当于锚点链接

<Link href="/dashboard#settings">Settings</Link>// Output
<a href="/dashboard#settings">Settings</a>

路由组

项目下新建三个路径文件

  • app/(marketing)/about/page.js
  • app/(marketing)/bolg/page.js
  • app/(marketing)/(shop)/acconut/page.js

在每个page.js里面随便写点内容,访问以下路径

  • localhost:3000/about
  • localhost:3000/bolg
  • localhost:3000/account

可以发现都能被访问到,总结规律就是文件夹名字带括号的相当于可以忽略了

路由组不参与url的设定的

个人感觉唯一作用是用于设置共同的Layout.js

创建如下两个Layout.js文件

  • app/(marketing)/Layout.js
  • app/(marketing)/(shop)/Layout.js

在这两个里面添加如下代码

export default function userLayout({ children }) {return (<section>marketing下面的layout{children}</section>);
}
export default function userLayout({ children }) {return (<section>marketing下面shop的layout{children}</section>);
}

运行后会发现,marking的Layout,js被它里面所有文件所共用,shop里面的Layout.js被shop里面的文件所共用,因为这个案例shop在marking里面的,因此shop里面的文件也共用marking里面的样式,这就是路由组,按照上面传统的方式建路由,需要每个文件单独设置自己的Layout.js,使用路由组可以达到复用性

动态路由

在app/user新建[username]文件夹,里面的page.js文件内容如下

export default function({params}){console.log('params',params);return <><div>我是user/[username]动态路由{params.username}</div></>
}

将app/page.js内容修改如下

'use client';
import Link from "next/link";
import { useRouter } from "next/navigation";export default function Home() {const router = useRouter()return (<><h1 className="text-4xl text-orange-600">Hello Name</h1><br></br><Link href={"/user/王二"}>跳转到user路由</Link><br></br><button onClick={()=>{router.push('/user/王五')}}>点击跳转/user</button></>);
}

当点击跳转到路由时,后面的参数就是动态参数,文件名username就是参数名,可以被params.username接收到并显示到页面上

上面有个弊端就是只支持一级动态参数,如果希望多级的话可以将[username]文件名换成[…username]这样就是可以匹配到后面所有参数,如下地址

  • localhost:3000/user/1/2/3/4/5

效果图

在这里插入图片描述
但是这里建议将[…username]文件名替换为[[…username]],两者区别在于[[…username]]当动态参数为空时也会被匹配到,剩余部分两者功能一致

Loadding加载和流的处理

1.在app下面新建Loading.js组件

export default function(){return <div className={"text-2xl text-pink-400"}>Loading...</div>
}

2.修改app/Layout.js

import { Inter } from "next/font/google";
import { Suspense } from "react";
import Loading from './loading';  // 引入app/loading.js
import "./globals.css";const inter = Inter({ subsets: ["latin"] });export const metadata = {title: "Create Next App",  // 网站标题description: "Generated by create next app", // 描述信息
};export default function RootLayout({ children }) {return (<html lang="en"><body className={inter.className}><Suspense fallback={<Loading></Loading>}> // 2.使用SusPense将页面包裹app下面的layout{children}</Suspense></body></html>);
}

子组件代码

这里使用了async/await模拟了一下异步,这是个细节,因为上面的loadding效果如果要出来的话,页面数据必须要是有异步效果,因为我没注意到这点,费了点时间才搞明白

export default async function Posts() {await new Promise((resolve) => setTimeout(resolve, 2000));return <div>1111</div>;
}

注意:将Lodding放到app/Layout.js里面包裹的话,则针对所有页面生效,如果某个页面有不一样的loading效果的话,则需要在当前文件夹里面的Layout.js去单独引入对应的Loading.js,可以在当前文件夹里面创建个Loading.js,这样的话Loading.js的样式仅仅作用于当前文件夹下的所有页面

import { Suspense } from "react";
export default function userLayout({ children }) {return (<section>// 这个loading效果仅作用于当前文件夹下面的所有页面<Suspense fallback={<div className={"text-2xl text-pink-400"}>Loading...</div>}>user下面的layout{children}</Suspense></section>);
}

注意:必须是渲染的页面内有异步操作(如async/await)才会有Loading.js效果

错误处理

新建app/error.js,放入以下内容

'use client'export default function({error,reset}){return (<div><h2>我是全局的错误样式处理</h2><button onClick={()=>reset()}>重试一下</button></div>)
}

也可以对每个页面单独定义路由样式,只需要在目标页面的文件夹内新建error.js,放入以下内容即可

例如我在app/user/error.js内加入以下内容

'use client'export default function({error,reset}){return (<div><h2>app/user 页面内有错误啦!!!</h2><button onClick={()=>reset()}>重试一下</button></div>)
}

例如我们在目标的user页面加入一些错误信息

export default function Posts() {console.log('a',a);  // 这里没有a变量,因此这里会报错return <div>1111</div>;
}

当我们在浏览器访问localhost:3000/user就会报出以下错误

在这里插入图片描述
当我们访问其他页面有错误信息时,但是没有给那个页面单独定义错误样式,则会触发全局的错误样式

例如访问: localhost:3000/about

在这里插入图片描述

组件化渲染

并行路线,也就是web端的组件

在app下面新建@home和@setting文件夹,里面都新建一个page.js文件,在里面写一点页面

在app/Layout.js里面改为如下页面代码

import { Inter } from "next/font/google";
import { Suspense } from "react";
import Loading from './loading';
import "./globals.css";const inter = Inter({ subsets: ["latin"] });export const metadata = {title: "Create Next App",  // 网站标题description: "Generated by create next app", // 描述信息
};export default function RootLayout({ children,home,setting }) {return (<html lang="en"><body className={inter.className}><Suspense fallback={<Loading></Loading>}>app下面的layout{home}{children}{setting}</Suspense></body></html>);
}

在这里插入图片描述

可以发现组件效果已经出来了

但是上面的仅限于在Layout.js里面使用的组件,下面是可以应用到我们页面里面的组件的案例

在app平级处创建components/frame/index.js,放入以下内容

import Image from "next/image";export default function({photo}){console.log('photo',photo);return <><Image src={photo.src} alt="" width={600} height={600} className={'w-full object-cover aspect-square col-span-2 w-28'}></Image></>
}

在app里面新建photo/page.js文件,插入以下内容

import Photo from "@/components/frame"  // 引入组件
export default function(){const photo = {src:'https://take-saas.oss-cn-hangzhou.aliyuncs.com/wechat_applets/coach/bgcimg/bgc-13.png'}// 给组件传值return <Photo photo={photo}></Photo>
}

注意:这里可能会报错图片问题(网络图片需要加一下白名单才能正常加载,如下在next.config.mjs里面进行配置)

/** @type {import('next').NextConfig} */
const nextConfig = {images:{domains:['take-saas.oss-cn-hangzhou.aliyuncs.com'] // 这里是存放域名白名单处}
};export default nextConfig;

然后就可以看到图片正常加载了

在这里插入图片描述

定义404页面

在app下面新建not-found.js,放入以下内容

export default function(){return <div className={"text-2xl text-pink-400"}>访问页面不存在...</div>
}

当页面访问一个不存在的页面路由时,页面显示效果如下

在这里插入图片描述
PS:由于博客内容都是自学做的整理,在某一次排查问题时,也就是刚好博客写到这里时,刷到了一个博主的nextjs教程合集,也挺详细的,力推点击进入合集地址

这篇关于Nextjs使用教程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/1031421

相关文章

Java 枚举的基本使用方法及实际使用场景

《Java枚举的基本使用方法及实际使用场景》枚举是Java中一种特殊的类,用于定义一组固定的常量,枚举类型提供了更好的类型安全性和可读性,适用于需要定义一组有限且固定的值的场景,本文给大家介绍Jav... 目录一、什么是枚举?二、枚举的基本使用方法定义枚举三、实际使用场景代替常量状态机四、更多用法1.实现接

springboot项目中使用JOSN解析库的方法

《springboot项目中使用JOSN解析库的方法》JSON,全程是JavaScriptObjectNotation,是一种轻量级的数据交换格式,本文给大家介绍springboot项目中使用JOSN... 目录一、jsON解析简介二、Spring Boot项目中使用JSON解析1、pom.XML文件引入依

Java中的record使用详解

《Java中的record使用详解》record是Java14引入的一种新语法(在Java16中成为正式功能),用于定义不可变的数据类,这篇文章给大家介绍Java中的record相关知识,感兴趣的朋友... 目录1. 什么是 record?2. 基本语法3. record 的核心特性4. 使用场景5. 自定

Python使用Tkinter打造一个完整的桌面应用

《Python使用Tkinter打造一个完整的桌面应用》在Python生态中,Tkinter就像一把瑞士军刀,它没有花哨的特效,却能快速搭建出实用的图形界面,作为Python自带的标准库,无需安装即可... 目录一、界面搭建:像搭积木一样组合控件二、菜单系统:给应用装上“控制中枢”三、事件驱动:让界面“活”

C/C++ chrono简单使用场景示例详解

《C/C++chrono简单使用场景示例详解》:本文主要介绍C/C++chrono简单使用场景示例详解,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友... 目录chrono使用场景举例1 输出格式化字符串chrono使用场景China编程举例1 输出格式化字符串示

Python验证码识别方式(使用pytesseract库)

《Python验证码识别方式(使用pytesseract库)》:本文主要介绍Python验证码识别方式(使用pytesseract库),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全... 目录1、安装Tesseract-OCR2、在python中使用3、本地图片识别4、结合playwrigh

Python使用Code2flow将代码转化为流程图的操作教程

《Python使用Code2flow将代码转化为流程图的操作教程》Code2flow是一款开源工具,能够将代码自动转换为流程图,该工具对于代码审查、调试和理解大型代码库非常有用,在这篇博客中,我们将深... 目录引言1nVflRA、为什么选择 Code2flow?2、安装 Code2flow3、基本功能演示

使用vscode搭建pywebview集成vue项目实践

《使用vscode搭建pywebview集成vue项目实践》:本文主要介绍使用vscode搭建pywebview集成vue项目实践,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录环境准备项目源码下载项目说明调试与生成可执行文件核心代码说明总结本节我们使用pythonpywebv

C++类和对象之默认成员函数的使用解读

《C++类和对象之默认成员函数的使用解读》:本文主要介绍C++类和对象之默认成员函数的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、默认成员函数有哪些二、各默认成员函数详解默认构造函数析构函数拷贝构造函数拷贝赋值运算符三、默认成员函数的注意事项总结一

使用Python和Matplotlib实现可视化字体轮廓(从路径数据到矢量图形)

《使用Python和Matplotlib实现可视化字体轮廓(从路径数据到矢量图形)》字体设计和矢量图形处理是编程中一个有趣且实用的领域,通过Python的matplotlib库,我们可以轻松将字体轮廓... 目录背景知识字体轮廓的表示实现步骤1. 安装依赖库2. 准备数据3. 解析路径指令4. 绘制图形关键