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教程合集,也挺詳細的,力推點擊進入合集地址

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/22429.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/22429.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/22429.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

使用Python操作Redis

大家好&#xff0c;在當今的互聯網時代&#xff0c;隨著數據量和用戶量的爆發式增長&#xff0c;對于數據存儲和處理的需求也日益增加。Redis作為一種高性能的鍵值存儲數據庫&#xff0c;以其快速的讀寫速度、豐富的數據結構支持和靈活的應用場景而備受青睞。本文將介紹Redis數…

貓頭虎分享已解決Bug || Error: ‘fetch‘ is not defined

原創作者&#xff1a; 貓頭虎 作者微信號&#xff1a; Libin9iOak 作者公眾號&#xff1a; 貓頭虎技術團隊 更新日期&#xff1a; 2024年6月6日 博主貓頭虎的技術世界 &#x1f31f; 歡迎來到貓頭虎的博客 — 探索技術的無限可能&#xff01; 專欄鏈接&#xff1a; &…

獨立游戲之路 -- 上架TapTap步驟和注意事項

個人開發者游戲上架TapTap上架步驟和注意事項 一、TapTap 介紹二、獨立游戲上架 TapTap 的步驟2.1 創建游戲2.2 提交游戲審核2.3 TapTap 平臺上發布。 三、注意事項3.1 關于備案3.2 遵守 TapTap 的規定3.3 保證游戲質量 四、常見問題4.1 隱私政策問題4.2 先發布還是先優化&…

C語言學習--鏈式結構

結構體的應用&#xff1a; //數據結構與算法 數據結構 ---- 指的是 數據的組織形式 數組 --- 數據結構 數組特點 連續性&#xff0c;有序性&#xff0c;單一性 數據操作&#xff08;訪問&#xff09;時的特點 -------------------…

Ubuntu24.04記錄網易郵箱大師的安裝

郵箱大師下載 官網自行下載&#xff0c;下載后文件名“mail.deb" https://dashi.163.com/ 安裝發現缺少依賴 #mermaid-svg-8wqpqFSBVOPD7NGP {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-8wqpqFSBVOPD7NGP …

PIVOT函數-動態列

一、需求說明 原始表&#xff1a; select * from pathogen_pro; 將pm_name的值轉成對應的列&#xff0c;效果如下 二、PIVOT函數說明 PIVOT(<聚合函數>([聚合列值]) FOR [行轉列前的列名] IN([行轉列后的列名1],[行轉列后的列名2],[行轉列后的列名3],.......[行轉列后…

Julia編程11:變量作用域 Scope of Variables

There are two main types of scopes in Julia, global* scope* and local* scope*. Julia有全局變量作用域和局部變量作用域&#xff0c;函數或者一些結構體、循環體如for等是否內部是局部環境可以參照下表。 ConstructScope typeAllowed withinmodule, baremoduleglobalglo…

.Net 基于.Net8開發的一個Asp.Net Core Webapi后端框架

1.項目結構 該項目是基于.net8開發的Asp.Net Core WebApi后端服務,集成了Efcore,Autofac,Jwt,AutoMapper,Serilog,Quartz,MiniExcel等組件。該框架簡單易上手&#xff0c;沒有額外的學習成本; 該項目采用了多層結構設計&#xff0c;有利于解耦&#xff0c;包含公共層&#xff0…

Linux入門學習指南

天行健&#xff0c;君子以自強不息&#xff1b;地勢坤&#xff0c;君子以厚德載物。 每個人都有惰性&#xff0c;但不斷學習是好好生活的根本&#xff0c;共勉&#xff01; 文章均為學習整理筆記&#xff0c;分享記錄為主&#xff0c;如有錯誤請指正&#xff0c;共同學習進步。…

MySQL數據庫整體知識點簡述

目錄 第一章&#xff1a;數據庫系統概述 第二章&#xff1a;信息與數據模型 第3章 關系模型與關系規范化理論 第四章——數據庫設計方法 第六-七章——MySQL存儲引擎與數據庫操作管理 第九章——索引 第10章——視圖 第11章——MySQL存儲過程與函數 第12章——MySQL 觸…

【SIPMRCP】freeswitch中的transfer和bridge有什么區別

在FreeSWITCH中&#xff0c;transfer和bridge是兩個用于處理通話的不同概念&#xff0c;它們之間的主要區別體現在功能和用途上。以下是關于這兩個概念的清晰解釋和區別&#xff1a; transfer&#xff08;轉移&#xff09; 功能&#xff1a;transfer主要用于將通話從一個目標…

IIS7整合Tomcat9服務器,并搭建ASP+PHP+JSP完整運行環境

本文以Windows Vista系統為例&#xff0c;詳細講解IIS7整合Tomcat服務器&#xff0c;同時支持ASPPHPJSP三種Web動態網頁技術的方法。 Vista系統自帶的IIS版本為7.0&#xff0c;能安裝的IE瀏覽器的最高版本為IE9。IE9也是Vue2前端框架支持的最低瀏覽器版本。 【準備工作】 去微…

【TB作品】msp430g2553單片機,讀取GY-30光強,串口發送

硬件 //GY-30 //SCL–P1.4 //SDA–P1.5 //VCC–3.3V //GND–GND //ADDR–不接 部分程序 #include <msp430.h> #include "gy30.h"void Send_Byte(char data) {while (!(IFG2 & UCA0TXIFG)); // USCI_A0 TX buffer ready?UCA0TXBUF data…

藍橋杯物聯網競賽_STM32L071_20_用printf將數據顯示在OLED上

需求&#xff1a; 第十五屆國賽確實有點變態&#xff0c;顯示部分大概有6個所以需要大量將sprintf與OLED_ShowString配合使用才能顯示相應格式的數據&#xff0c;所以我在想能不能簡化一下這一部分直接用寫好的printf語句將數據顯示到顯示屏上呢&#xff1f; 代碼&#xff1a…

樹--搜索二叉樹

現有一棵結點數目為n的二叉樹&#xff0c;采用二叉鏈表的形式存儲。對于每個結點均有指向左右孩子的兩個指針域&#xff0c;而結點為n的二叉樹一共有n-1條有效分支路徑。那么&#xff0c;則二叉鏈表中存在2n-(n-1)n1個空指針域。那么&#xff0c;這些空指針造成了空間浪費。 例…

【TB作品】msp430g2553單片機,秒表,LCD1602,Proteus仿真

功能 秒表 動圖&#xff1a; 部分代碼 這段代碼是用C語言編寫的&#xff0c;用于在基于德州儀器MSP430微控制器的平臺上實現一個簡易的電子秒表功能。 #include <msp430.h> #include "LCD.h"unsigned int second 0; unsigned int millisecond10…

【HarmonyOS】應用振動效果實現

一、問題背景&#xff1a; 應用在強提醒場景下&#xff0c;一般會有馬達振動的效果&#xff0c;提示用戶注意力的關注。 比如消息提醒&#xff0c;掃碼提示&#xff0c;刪除鍵確認提示等。 針對高定制化或者固定的振動方式&#xff0c;我們需要有不同的方案實現&#xff0c;馬…

php項目加密源碼

軟件簡介 壓縮包里有多少個php就會被加密多少個PHP、php無需安裝任何插件。源碼全開源 如果上傳的壓縮包里有子文件夾&#xff08;子文件夾里的php文件也會被加密&#xff09;&#xff0c;加密后的壓縮包需要先修復一下&#xff0c;步驟&#xff1a;打開壓縮包 》 工具 》 修…

【云原生】Kubernetes----Ingress對外服務

目錄 引言 一、K8S對外方式 &#xff08;一&#xff09;NodePort 1.作用 2.弊端 3.示例 &#xff08;二&#xff09;externalIPs 1.作用 2.弊端 3.示例 &#xff08;三&#xff09;LoadBalancer 1.作用 2.弊端 &#xff08;四&#xff09;Ingress 二、Ingress的…

Linux文件I/O與標準I/O緩沖機制及性能分析

目錄 1、文件I/O 1.1、數據緩沖機制 1.2、性能影響 2、標準I/O 2.1、數據緩沖機制 2.2、性能影響 3、文件I/O與標準I/O的對比 在Linux中&#xff0c;文件I/O和標準I/O是兩種常見的I/O操作方式&#xff0c;它們在數據緩沖的原理和機制上有所不同。理解這些原理和機制對優…