為什么需要使用Next.js
react/vue/angular: 雖然是單頁(yè)面應(yīng)用,但是會(huì)導(dǎo)致首屏加載過(guò)慢,不利于SEO, Next.js 是一個(gè)輕量級(jí)的 React 服務(wù)端渲染應(yīng)用框架,用服務(wù)端渲染(SSR)可以解決以上兩個(gè)問(wèn)題。
Next.js的優(yōu)點(diǎn)
- 搭建輕松
- 自帶數(shù)據(jù)同步 SSR
- 有豐富的插件 自己形成了生態(tài)
- 靈活的配置
Next.js簡(jiǎn)單的項(xiàng)目搭建
使用腳手架進(jìn)行全局安裝
npm install -g create-next-app
創(chuàng)建Next.js的項(xiàng)目
$ npx create-next-app next-demo //next-demo是項(xiàng)目名
在瀏覽器中輸入http://localhost:3000/ 檢測(cè)項(xiàng)目是否生成成功
Next.js的項(xiàng)目結(jié)構(gòu)的介紹
每個(gè)頁(yè)面都是 React 組件(核心~)
- components文件夾: 用來(lái)存放公用的或者有專門用途的組件。
- node_modules文件夾:Next項(xiàng)目的所有依賴包都在這里,一般我們不用修改和編輯這里的內(nèi)容。
- pages文件夾:這里是放置頁(yè)面的,這里邊的內(nèi)容會(huì)自動(dòng)生成路由,并在服務(wù)器端渲染,渲染好后進(jìn)行數(shù)據(jù)同步。
- static文件夾: 這個(gè)是靜態(tài)文件夾,比如項(xiàng)目需要的圖片、圖標(biāo)、css文件等靜態(tài)資源都可以放到這里。
Next.js的路由簡(jiǎn)介
1.路由的跳轉(zhuǎn)
有兩種路由跳轉(zhuǎn)方式
// ①標(biāo)簽式跳轉(zhuǎn)
// 小坑勿踩: {/* link下邊只能有一個(gè)根元素,不能有并列的兄弟元素, 所以可以用a標(biāo)簽進(jìn)行包裹 */}
import Link from 'next/link';
<Link href="/jspangA"><a>A頁(yè)面</a></Link>
// ②編程式跳轉(zhuǎn) 耦合性比較低
import Router from 'next/router';
function testRouterDemo(){
Router.push({
pathname: '/test'
})
}
2. 路由傳參
// 只能使用query?id = 1進(jìn)行傳參 不支持path:id來(lái)傳參
①<Link href="/test?name=one"><a>標(biāo)簽式</a></Link>
<Link href={{pathname: '/test', query: {name: 'test'}}}><a>標(biāo)簽式</a></Link>
② function gotoBlue(){
Router.push({
pathname: '/test',
query: {name: 'one'}
})
}
3.路由的接收參數(shù)
使用withRouter組件來(lái)進(jìn)行參數(shù)的接收
import { withRouter} from 'next/router' // 用來(lái)接受參數(shù)的
import Link from 'next/link'
const GetParamCom = ({router})=>{ // 如果不引入withRouter,就沒(méi)有這個(gè)函數(shù)里的參數(shù)
return (
<> // 可以使用空標(biāo)簽進(jìn)行元素的包裹
<div>{router.query.name},獲取地址欄的參數(shù) .</div>
<Link href="/"><a>返回首頁(yè)</a></Link>
</>
)
}
export default withRouter(GetParamCom) // withRouter有著路由技能的裝備
路由的鉤子事件
// routeChangeStart ==> 路由發(fā)生變化之前
// routeChangeComplete ==> 發(fā)生結(jié)束變化時(shí)
// beforeHistoryChange ==> 瀏覽器history觸發(fā)前
// routeChangeError ==> 路由跳轉(zhuǎn)發(fā)生錯(cuò)誤的時(shí)候
// hashChangeStart ==> 轉(zhuǎn)變成hash路由模式開(kāi)始執(zhí)行
// hashChangeComplete ===》轉(zhuǎn)變成hash路由模式完成執(zhí)行
Next.js的getInitialProps靜態(tài)方法的介紹
當(dāng)頁(yè)面初始化加載時(shí),getInitialProps只會(huì)加載在服務(wù)端。只有當(dāng)路由跳轉(zhuǎn)(Link組件跳轉(zhuǎn)或 API 方法跳轉(zhuǎn))時(shí),客戶端才會(huì)執(zhí)行g(shù)etInitialProps。
我們可以簡(jiǎn)單的理解getInitialProps是react生命周期的擴(kuò)充,他是Next.js一個(gè)的一個(gè)偉大的發(fā)明,是實(shí)現(xiàn)服務(wù)端渲染的重要的方法,Next.js 會(huì)調(diào)用 getInitialProps 來(lái)獲取數(shù)據(jù),然后把獲得數(shù)據(jù)作為 props 來(lái)啟動(dòng) React 組件的原本生命周期。我們不用關(guān)心getInitialProps什么時(shí)候被調(diào)用,這些都可以交給Next.js來(lái)完成。
getInitialProps靜態(tài)方法是用來(lái)獲取遠(yuǎn)端數(shù)據(jù),這是這個(gè)框架的約定,所以我們要遵循框架的約定,不要試圖在生命周期中獲取遠(yuǎn)端的數(shù)據(jù)。
注意:getInitialProps將不能使用在子組件中。只能使用在pages頁(yè)面中。
例子:
const Test = ({list}) => { //因?yàn)樵趃etInitialProps這里請(qǐng)求的遠(yuǎn)程數(shù)據(jù)的key是list,所以在這個(gè)組件中可以直接使用
return(
<>
<div>{list}</div>
</>
)
}
Test.getInitialProps = async() => { // 因?yàn)檎?qǐng)求有時(shí)差 所以用異步進(jìn)行操作
const promise = new Promise((resolve) => {
axios('接口請(qǐng)求地址').then(
(res) => {
console.log('result:', res);
resolve(res.data.data); // 獲取成功了就告訴resolve,然后把結(jié)果返回出去
}
)
})
return await promise;
}
export default Test;
getInitialProps的入?yún)?duì)象的簡(jiǎn)介
- pathname - URL 的 path 部分
- query - URL 的 query 部分,并被解析成對(duì)象
- asPath - 顯示在瀏覽器中的實(shí)際路徑(包含查詢部分),為String類型
- req - HTTP 請(qǐng)求對(duì)象 (只有服務(wù)器端有)
- res - HTTP 返回對(duì)象 (只有服務(wù)器端有)
- jsonPageRes - 獲取數(shù)據(jù)響應(yīng)對(duì)象 (只有客戶端有)
- err - 渲染過(guò)程中的任何錯(cuò)誤
eg.
Test.getInitialProps = async( { pathname } ) => {
const promise = new Promise((resolve) => {
axios('接口請(qǐng)求地址').then(
(res) => {
console.log(pathname) // 可以幫助獲取URL的path部分
}
)
})
return await promise;
}
使用style jsx來(lái)進(jìn)行編寫css樣式
加入了Style jsx代碼后,Next.js會(huì)自動(dòng)加入一個(gè)隨機(jī)類名,這樣就防止了CSS的全局污染
// next是不支持css文件的
import React, {useState} from 'react';
function Style(){
const [color, setColor] = useState('blue');
const changeColor = () => {
setColor(color === 'blue' ? 'red ' : 'blue');
}
return (
<>
<span className="test">style jsx</span>
<div><button onClick={changeColor}>改變顏色</button></div>
{/* 動(dòng)態(tài)的css樣式 */}
<style jsx>
{`
div{color: ${color}}
.test{color: red;}
`}
</style>
</>
)
}
export default Style;
模塊的懶加載
- 懶加載模塊(react中模塊的理解一般是指的外部庫(kù))
- 一般使用懶加載的場(chǎng)景:不是主要的業(yè)務(wù)邏輯,所以不用及時(shí)去加載這些外部庫(kù) 所以使用懶加載
我們以外部的moment庫(kù)作為模板進(jìn)行測(cè)試
import React, {useState} from 'react';
function Time(){
const [time, SetTime] = useState(Date.now());
const formatTime = async() => {
const moment = await import('moment'); // ① 引入的時(shí)候是需要時(shí)間的,所以這些外部庫(kù) 在需要的時(shí)候再進(jìn)入
SetTime(moment.default(Date.now()).format())
}
return (
<>
<div>顯示時(shí)間為: {time}</div>
<button onClick={formatTime}>改變時(shí)間格式</button> // 點(diǎn)擊的時(shí)候才會(huì)去調(diào)用外部模塊
</>
)
}
export default Time;
- 懶加載自定義組件
import React, {useState} from 'react';
import dynamic from 'next/dynamic'; // 用來(lái)懶加載組件
const CustomCom = dynamic(import('../components/customCom')); // ②只有執(zhí)行到渲染CustomCom的時(shí)候才會(huì)加載進(jìn)來(lái),控制臺(tái)可以看出來(lái)
function CustomComponent(){
return (
<>
<CustomCom></CustomCom>
</>
)
}
export default CustomComponent;
如何在Next.js中使用Ant-design UI框架
首要問(wèn)題是解決Next.js對(duì)css的支持問(wèn)題:
1. npm install --save @zeit/next-css // 添加相應(yīng)的包 實(shí)現(xiàn)對(duì)css的支持
2. 在項(xiàng)目的根目錄下創(chuàng)建next.config.js進(jìn)行相關(guān)的配置(配置內(nèi)容如下)
const withCss = require('@zeit/next-css')
if(typeof require !== 'undefined'){
require.extensions['.css']=file=>{}
}
module.exports = withCss({})
3.重啟一下服務(wù),就可以實(shí)現(xiàn)在Next中編寫css文件了 是不是很開(kāi)心哇~
按需加載Ant的模塊
1. npm install --save babel-plugin-import
2. 安裝完成后,在項(xiàng)目根目錄建立.babelrc文件,然后寫入如下配置文件。
{
"presets":["next/babel"], //Next.js的總配置文件,相當(dāng)于繼承了它本身的所有配置
"plugins":[ //增加新的插件,這個(gè)插件就是讓antd可以按需引入,包括CSS
[
"import",
{
"libraryName":"antd",
"style":"css"
}
]
]
}
總結(jié)
希望這點(diǎn)簡(jiǎn)單的介紹 可以給需要的小伙伴帶來(lái)一點(diǎn)幫助哈~??