React腳手架之NextJs
1.Next.js簡介
Next.js 是一個輕量級的 React 服務端渲染應用框架。
它的優點:
- 完善的React專案架構,搭建輕鬆。比如:Webpack配置,伺服器啟動,路由配置,快取能力,這些在它內部已經完善的為我們搭建完成了。
- 自帶資料同步策略,解決服務端渲染最大難點。把服務端渲染好的資料,拿到客戶端重用,這個在沒有框架的時候,是非常複雜和困難的。有了Next.js,它為我們提供了非常好的解決方法,讓我們輕鬆的就可以實現這些步驟。
- 豐富的外掛幫開發人員增加各種功能。每個專案的需求都是不一樣的,包羅永珍。無所不有,它為我們提供了外掛機制,讓我們可以在使用的時候按需使用。你也可以自己寫一個外掛,讓別人來使用。
- 靈活的配置,讓開發變的更簡單。它提供很多靈活的配置項,可以根據專案要求的不同快速靈活的進行配置。
2.快速建立Next.js
#全域性安裝
npm install -g create-next-app
#npx建立專案
npx install create-next-app demo13
cd demo13
#本地執行
yarn dev
3.專案結構介紹
- components資料夾:這裡是專門放置自己寫的元件的,這裡的元件不包括頁面,指公用的或者有專門用途的元件。
- node_modules資料夾:Next專案的所有依賴包都在這裡,一般我們不會修改和編輯這裡的內容。
- pages資料夾:這裡是放置頁面的,這裡邊的內容會自動生成路由,並在伺服器端渲染,渲染好後進行資料同步。
- static資料夾: 這個是靜態資料夾,比如專案需要的圖片、圖示和靜態資源都可以放到這裡。
- .gitignore檔案: 這個主要是控制git提交和上傳檔案的,簡稱就是忽略提交。
- package.json檔案:定義了專案所需要的檔案和專案的配置資訊(名稱、版本和許可證),最主要的是使用
npm install
就可以下載專案所需要的所有包。
4.Page和Component使用
在pages檔案下,建立Test.js。
function Test(){
return (<button> Test page</button>)
}
export default Test;
寫完以上的程式碼,Next
框架就自動作好了路由,這個也算是Next的一個重要優點,給我們節省了大量的時間。
現在要作一個更深的頁面,比如把有關部落格的介面都放在這樣的路徑下http://localhost:3000/blog/nextBlog
,其實只要在pages
資料夾下再建立一個新的資料夾blog
,然後進入blog
資料夾,新建一個nextBlog.js
檔案,就可以實現了。
編寫元件也特別方便,比如要建立一個comm元件,直接在components
目錄下建立一個檔案comm,然後寫入下面程式碼:
export default ({children})=><button>{children}</button>
元件寫完後需要先引入,比如我們在Index頁面裡進行引入:
import comm from '../components/comm'
使用就非常簡單了,直接寫入標籤就可以。
<comm>按鈕</comm>
5.路由基礎及跳轉
5.1 標籤是導航
首先先刪除index.js中的程式碼,引入以下:
import Link from 'next/link'
然後新建兩個頁面testA.js
和testB.js
import Link from 'next/link'
export default ()=>(
<>
<div>TestA page . </div>
<Link href="/"><a>返回首頁</a></Link>
</>
)
import Link from 'next/link'
export default ()=>(
<>
<div>TestB page . </div>
<Link href="/"><a>返回首頁</a></Link>
</>
)
然後編寫index檔案
import React from 'react'
import Link from 'next/link'
const Home = () => (
<>
<div>我是首頁</div>
<div><Link href="/testA"><a>去testA頁面</a></Link></div>
<div><Link href="/testB"><a>去testB頁面</a></Link></div>
</>
)
export default Home
注意:不支援兄弟並列標籤。
5.2 Router模組跳轉
在index.js中,新增以下:
<div>
<button onClick={()=>{Router.push('/testA')}}>去testA頁面</button>
</div>
6.路由跳轉傳值和接收引數
6.1 query傳遞引數及接收
<div><Link href="/testA?name=karma"><a>Link跳轉去testA頁面</a></Link></div>
//或
<div><Link href={{pathname: '/testA', query: {name: 'karma'}}}><a>Link跳轉去testA頁面</a></Link></div>
然後在testA.js檔案中接收該引數:
import React from 'react'
import Link from 'next/link'
import {withRouter} from "next/router";
const testA = ({router}) => (
<>
<div>testA page . {router.query.name}</div>
<Link href="/"><a>返回首頁</a></Link>
</>
)
//withRouter是Next.js框架的高階元件,用來處理路由用的
export default withRouter(testA)
6.2 Router程式設計式傳遞引數
<button onClick={()=>{Router.push('/testA?name=karma')}}>去testA頁面</button>
#或者
<button onClick={()=>{Router.push({
pathname:'/testA',
query:{
name:'karma'
}
})}>去testA頁面</button>
7.路由-六個鉤子事件
routerChangeStart
路由發生變化
Router.events.on('routeChangeStart',(...args)=>{
console.log('1.routeChangeStart->路由開始變化,引數為:',...args)
})
routerChangeComplete
路由結束變化時
Router.events.on('routeChangeComplete',(...args)=>{
console.log('routeChangeComplete->路由結束變化,引數為:',...args)
})
beforeHistoryChange
瀏覽器history觸發前
Router.events.on('beforeHistoryChange',(...args)=>{
console.log('3,beforeHistoryChange->在改變瀏覽器 history之前觸發,引數為:',...args)
})
routeChangeError
路由跳轉發生錯誤時
Router.events.on('routeChangeError',(...args)=>{
console.log('4,routeChangeError->跳轉發生錯誤,引數為:',...args)
})
需要注意的是404找不到路由頁面不算錯誤。
轉變成hash路由模式
還有兩種事件,都是針對hash的,所以現在要轉變成hash模式。hash模式下的兩個事件hashChangeStart
和`hashChangeComplete。
Router.events.on('hashChangeStart',(...args)=>{
console.log('5,hashChangeStart->hash跳轉開始時執行,引數為:',...args)
})
Router.events.on('hashChangeComplete',(...args)=>{
console.log('6,hashChangeComplete->hash跳轉完成時,引數為:',...args)
})
在下面的jsx語法部分,再增加一個連結,使用hash來進行跳轉,程式碼如下:
<div>
<Link href="#test"><a>test</a></Link>
</div>
8.在getInitialProps中使用Axios獲取遠端資料
在Next.js
框架中提供了getInitialProps
靜態方法用來獲取遠端資料,這個是框架的約定,所以你也只能在這個方法裡獲取遠端資料。
安裝Axios:
yarn add axios
在testA.js中引入Axios
import Axios from 'axios'
然後使用getInitialProps獲取遠端資料並渲染頁面
import React from 'react'
import Link from 'next/link'
import {withRouter} from "next/router";
import Axios from "axios";
const testA = ({router, list}) => (
<>
<div>testA page . {router.query.name} {list}</div>
<Link href="/"><a>返回首頁</a></Link>
</>
)
testA.getInitialProps = async () => {
const promise = new Promise((resolve => {
Axios('https://www.easy-mock.com/mock/5f96cc6134c55d14fda96ea1/example/query').then((res) => {
console.log('遠端資料結果:', res)
resolve(res.data.data)
})
}))
return await promise
}
//withRouter是Next.js框架的高階元件,用來處理路由用的
export default withRouter(testA)
9.使用style JSX編寫頁面的css樣式
在pages檔案下,建立testC.js.
function testC(){
return (
<>
<div>testC</div>
<style jsx>
{`
div{color:blue;}
`}
</style>
</>
)
}
export default testC
通過自定義類名載入css
function testC(){
return (
<>
<div>testC</div>
<div className="karma">karma</div>
<style jsx>
{`
div{color:blue;},
.karma{color:red}
`}
</style>
</>
)
}
export default testC
動態顯示樣式
import {useState} from "react";
function testC() {
const [color, setColor] = useState('blue')
const changeColor = () => {
setColor(color === 'blue' ? 'red' : 'blue')
}
return (
<>
<div>testC</div>
<div>
<button onClick={changeColor}>改變顏色</button>
</div>
<div className="karma">karma</div>
{/*Style JSX語法*/}
<style jsx>
{`
div{color:${color};},
`}
</style>
</>
)
}
export default testC
10.Lazy Loading 實現模組懶載入
懶載入模組
安裝moment
yarn add moment
然後在pages
資料夾下,新建立一個time.js
檔案,並使用剛才的moment
庫來格式化時間,程式碼如下:
import React, {useState} from 'react'
import moment from 'moment'
function Time(){
const [nowTime,setTime] = useState(Date.now())
const changeTime=()=>{
setTime(moment(Date.now()).format())
}
return (
<>
<div>顯示時間為:{nowTime}</div>
<div><button onClick={changeTime}>改變時間格式</button></div>
</>
)
}
export default Time
這個案例,存在著一個潛在的風險,就是如何有半數以上頁面使用了這個momnet
的庫,那它就會以公共庫的形式進行打包釋出,就算專案第一個頁面不使用moment
也會進行載入,這就是資源浪費,對於我這樣有程式碼潔癖的良好程式設計師是絕對不允許的。下面我們就通過Lazy Loading
來進行改造程式碼。
import React, {useState} from 'react'
//刪除import moment
function Time(){
const [nowTime,setTime] = useState(Date.now())
const changeTime= async ()=>{ //把方法變成非同步模式
const moment = await import('moment') //等待moment載入完成
setTime(moment.default(Date.now()).format()) //注意使用defalut
}
return (
<>
<div>顯示時間為:{nowTime}</div>
<div><button onClick={changeTime}>改變時間格式</button></div>
</>
)
}
export default Time
懶載入自定義元件
先寫一個最簡單的元件,在components
資料夾下建立一個one.js
檔案,然後編寫如下程式碼:
export default ()=><div>Lazy Loading Component</div>
有了自定義元件後,先要在懶載入這個元件的檔案中引入dynamic
,我們這個就在上邊新建的time.js
檔案中編寫了。
import dynamic from 'next/dynamic'
引入後就可以懶載入自定義模組了,程式碼如下:
import React, {useState} from 'react'
import dynamic from 'next/dynamic'
const One = dynamic(import('../components/one'))
function Time(){
const [nowTime,setTime] = useState(Date.now())
const changeTime= async ()=>{
const moment = await import('moment')
setTime(moment.default(Date.now()).format())
}
return (
<>
<div>顯示時間為:{nowTime}</div>
<One/>
<div><button onClick={changeTime}>改變時間格式</button></div>
</>
)
}
export default Time
11.自定義Head更加友好的SEO操作
一般有兩種方式。
方法1:在各頁面加上標籤
先在/pages
資料夾下面建立一個header.js
檔案,然後寫一個最簡單的Hooks
頁面,程式碼如下:
function Header(){
return (<div>JSPang.com</div>)
}
export default Header
寫完後到瀏覽器中預覽一下,可以發現title部分並沒有任何內容,顯示的是localhost:3000/header
,接下來就自定義下<Head>
。自定義需要先進行引入next/head
。
import Head from 'next/head'
引入後你就可以寫一些列的頭部標籤了,全部程式碼如下:
import Head from 'next/head'
function Header(){
return (
<>
<Head>
<title>Header</title>
<meta charSet='utf-8' />
</Head>
<div>Karma520.com</div>
</>
)
}
export default Header
這時候再開啟瀏覽器預覽,你發現已經有了title
。
方法2:全域性定義
比如在components
資料夾下面新建立一個myheader.js
,然後寫入下面的程式碼:
import Head from 'next/head'
const MyHeader = ()=>{
return (
<>
<Head>
<title> Karma520.com </title>
</Head>
</>
)
}
export default MyHeader
把剛才編寫的header.js
頁面改寫一下,引入自定義的myheader
,在頁面裡進行使用。
import Myheader from '../components/myheader'
function Header(){
return (
<>
<Myheader />
<div>Karma520.com</div>
</>
)
}
export default Header
12.Next.js腳手架中使用Ant Design UI
Next.js
預設是不支援CSS檔案的,它用的是style jsx
,也就是說它是不支援直接用import
進行引入css
的。
在static下新建一個test.css
檔案,寫入一些CSS Style
。
body{
color:green;
}
然後用import
在header.js
裡引入。
import '../static/test.css'
寫完到瀏覽器中進行預覽,沒有任何輸出結果而且報錯了。這說明Next.js
預設是不支援CSS樣式引入的,要進行一些必要的設定,才可以完成。
開始進行配置,讓Next.js支援CSS檔案
先用yarn
命令來安裝@zeit/next-css
包,它的主要功能就是讓Next.js
可以載入CSS檔案。
yarn add @zeit/next-css
包安裝好以後就可以進行配置檔案的編寫了,建立一個next.config.js
.這個就是Next.js
的總配置檔案(如果感興趣可以自學一下)。
const withCss = require('@zeit/next-css')
if(typeof require !== 'undefined'){
require.extensions['.css']=file=>{}
}
module.exports = withCss({})
重啟服務可以讓配置生效,這時候你到瀏覽器中可以發現CSS檔案已經生效了,字變成了綠色。
按需載入Ant Design
載入Ant Design
在我們打包的時候會把Ant Design
的所有包都打包進來,這樣就會產生效能問題,讓專案載入變的非常慢。
** 先來安裝Ant Design
庫 **
直接使用yarn來安裝就可以。
yarn add antd
** 安裝和配置babel-plugin-import
外掛 **
yarn add babel-plugin-import
然後在專案根目錄建立.babelrc
檔案,然後寫入如下配置檔案。
{
"presets":["next/babel"], //Next.js的總配置檔案,相當於繼承了它本身的所有配置
"plugins":[ //增加新的外掛,這個外掛就是讓antd可以按需引入,包括CSS
[
"import",
{
"libraryName":"antd",
"style":"css"
}
]
]
}
配置好了以後,webpack
就不會預設把整個Ant Design
的包都進行打包到生產環境了,而是我們使用那個元件就打包那個元件,同樣CSS也是按需打包的。
然後在header.js裡,引入
`元件,並進行使用。
import Myheader from '../components/myheader'
import {Button} from 'antd'
import '../static/test.css'
function Header(){
return (
<>
<Myheader />
<div>Karma520.com</div>
<div><Button>按鈕</Button></div>
</>
)
}
export default Header
執行,看效果。
13.Next打包CSS問題
打包 :yarn build
然後在終端裡執行一下yarn build
,如果這時候報錯,其實是我們在加入Ant Design
的樣式時產生的,這個已經在Ant Design
的Github上被提出了,但目前還沒有被修改,你可以改完全域性引入CSS解決問題。
在page目錄下,修改_app.js
檔案。
import App from 'next/app'
import 'antd/dist/antd.css'
export default App
並且註釋.babelrc中該行配置 “style”:“css”,然後執行命令。
個人部落格:Karma‘s Blog
原始碼地址:傳送門
相關文章
- React入門---react腳手架React
- 服務端渲染的React手腳架。完美使用 React, Redux, and React-Router!最好用的腳手架服務端ReactRedux
- Dva手腳架搭建React專案React
- react+typescript+antd腳手架搭建ReactTypeScript
- 基於React的腳手架搭建React
- React(腳手架)——create-react-app擼api(三)ReactAPPAPI
- webpack+react+antd腳手架優化WebReact優化
- 基於vite2的react腳手架ViteReact
- React筆記:快速構建腳手架(1)React筆記
- Vite 2.0 + React + TypeScript + Antd 搭建簡單腳手架ViteReactTypeScript
- 從零開始搭建一個 React + Mobx + React Router 腳手架React
- vue腳手架Vue
- 七天接手react專案 系列 —— react 腳手架建立專案React
- 開發 react 應用最好用的腳手架 create-react-appReactAPP
- 有個功能豐富的 react 腳手架,瞭解下?React
- React多頁面應用腳手架-v1.3.0React
- 新手搭建簡潔的Express-React-Redux腳手架ExpressReactRedux
- 什麼是腳手架?為什麼需要腳手架?常用的腳手架有哪些?
- VUE學習之腳手架(vue-cli)Vue
- react+antd 使用腳手架動態修改主題色React
- 基於webpack4.X從零搭建React腳手架WebReact
- vue - Vue腳手架Vue
- 腳手架與混入
- vue腳手架工具Vue
- 不借助腳手架手動搭建react專案(webpack5 + Antd4 + React18)ReactWeb
- vue實踐01之vue-cli腳手架Vue
- 用webpack4從零開始構建react腳手架WebReact
- 小邵教你玩轉Typescript、ts版React全家桶腳手架TypeScriptReact
- 擺脫create-react-app,來讓我們自己搭建一個react腳手架ReactAPP
- 9102年:手寫一個React腳手架 【已優化至完美版】React優化
- vue腳手架基礎Vue
- plop小型腳手架工具
- react 高效高質量搭建後臺系統 系列 —— 腳手架搭建React
- 使用腳手架建立Vue程式Vue
- vue - Vue腳手架/TodoList案例Vue
- 分享一個springboot腳手架Spring Boot
- 如何用vue搭建腳手架Vue
- 小型前端腳手架工具Plop前端