Next.js(代碼示例均使用hook函數(shù)式聲明)
1.特點(diǎn)
1.1 完善的React項(xiàng)目架構(gòu),搭建輕松
??Webpack配置,服務(wù)器啟動(dòng),路由配置,緩存能力,這些在它內(nèi)部已經(jīng)完善的為我們搭建完成了(create-next-app)
1.2 自帶數(shù)據(jù)同步策略,解決服務(wù)端渲染最大難點(diǎn)
1.3 豐富的插件幫開發(fā)人員增加各種功能
1.4 靈活的配置,讓開發(fā)變的更簡單
2.安裝
npm install -g create-next-app
npm create-next-app next-create
2.1 項(xiàng)目結(jié)構(gòu)
??components文件夾:這里是專門放置自己寫的組件的,這里的組件不包括頁面,指公用的或者有專門用途的組件。
??pages文件夾:這里是放置頁面的,這里邊的內(nèi)容會(huì)自動(dòng)生成路由,并在服務(wù)器端渲染,渲染好后進(jìn)行數(shù)據(jù)同步。
??static文件夾: 這個(gè)是靜態(tài)文件夾,比如項(xiàng)目需要的圖片、圖標(biāo)和靜態(tài)資源都可以放到這里。
??package.json文件:定義了項(xiàng)目所需要的文件和項(xiàng)目的配置信息(名稱、版本和許可證),最主要的是使用npm install 就可以下載項(xiàng)目所需要的所有包。
3.編寫頁面
??在pages下新建好js頁面,nextjs自動(dòng)會(huì)配置路由。異常方便
<!-- helloA.js 直接訪問/helloA即可訪問. 訪問目錄next/helloWorld.js 直接訪問 /next/helloWorld -->
export default () => (
<div>
<h1>this is A page</h1>
</div>
)
4.路由跳轉(zhuǎn)和query傳遞參數(shù)
??頁面跳轉(zhuǎn)一般有兩種形式,第一種是利用標(biāo)簽Link,第二種是用js編程的方式進(jìn)行跳轉(zhuǎn),也就是利用Router組件。在Next.js中只能通過query(?id=1)來傳遞參數(shù)比如。
import Link from 'next/link'
import Router from 'next/router'
function gotoNews() {
// Router.push('/news?name=Durant') 或者下面這種
Router.push({
pathname: '/news',
query: {
name: 'Durant'
}
})
}
<li>攜帶參數(shù)路由跳轉(zhuǎn)</li>
<div>
<div> <Link href="/news?name=james"><a>james</a></Link></div>
<div> <Link href={{ pathname: '/news', query: { name: 'wade' } }}><a>wade</a></Link></div>
</div>
<li>編程式路由跳轉(zhuǎn)</li>
<div>
<button onClick={gotoNews}>杜蘭特</button>
</div>
//另一個(gè)頁面接受參數(shù)
return (
<div>
<div>{router.query.name}is MVP</div>
<Link href="/"><a>返回首頁</a></Link>
</div>
)
export default withRouter(News)
5.路由中六個(gè)鉤子事件
??路由的鉤子事件,也就是當(dāng)路由發(fā)生變化時(shí),可以監(jiān)聽到這些變化事件,執(zhí)行對(duì)應(yīng)的函數(shù)。它一共有六個(gè)鉤子事件。如下
//路由變化時(shí)
Router.events.on('routeChangeStart', (...args) => {
console.log('1.routeChangeStart->路由開始變化,參數(shù)為:', ...args)
})
//路由變化結(jié)束
Router.events.on('routeChangeComplete', (...args) => {
console.log('2.routeChangeComplete->路由結(jié)束變化,參數(shù)為:', ...args)
})
//觸發(fā)history前
Router.events.on('beforeHistoryChange', (...args) => {
console.log('3,beforeHistoryChange->在改變?yōu)g覽器 history之前觸發(fā),參數(shù)為:', ...args)
})
//路由跳轉(zhuǎn)發(fā)生錯(cuò)誤 需要注意的是404找不到路由頁面不算錯(cuò)誤
Router.events.on('routeChangeError', (...args) => {
console.log('4,routeChangeError->跳轉(zhuǎn)發(fā)生錯(cuò)誤,參數(shù)為:', ...args)
})
//hash 路由跳轉(zhuǎn)模式
Router.events.on('hashChangeStart', (...args) => {
console.log('5,hashChangeStart->hash跳轉(zhuǎn)開始時(shí)執(zhí)行,參數(shù)為:', ...args)
})
Router.events.on('hashChangeComplete', (...args) => {
console.log('6,hashChangeComplete->hash跳轉(zhuǎn)完成時(shí),參數(shù)為:', ...args)
})
6.在getInitialProps用axios請(qǐng)求數(shù)據(jù)
??在Next.js框架中提供了getInitialProps靜態(tài)方法用來獲取遠(yuǎn)端數(shù)據(jù),這個(gè)是框架的約定,所以你也只能在這個(gè)方法里獲取遠(yuǎn)端數(shù)據(jù)。(也可以在componentDidMount中獲得但是不推薦)
const Player = ({router,list})=>{
return (
<div>
<div>{router.query.name} is MVP</div>
<Link href="/"><a>返回首頁</a></Link>
</div>
)
}
Player.getInitialProps = async ()=>{
const promise =new Promise((resolve)=>{
axios('url').then(
(res)=>{
console.log('遠(yuǎn)程數(shù)據(jù)結(jié)果:',res)
resolve(res.data.data)
}
)
})
return await promise
}
export default withRouter(Player)
7.使用Style jsx 編寫css樣式
??在Next.js中引入一個(gè)CSS樣式是不可以用的,如果想用,需要額外的配置。nextjs框架為我們提供了一個(gè)style jsx特性,也就是把CSS用JSX的語法寫出來。
import React, { useState } from 'react'
export default function helloColor() {
const [color, setColor] = useState('lightgreen')
const changeColor = () => {
setColor(color == 'lightgreen' ? 'red' : 'yellow')
}
return (
<div>
<div>
<h1>color</h1>
<button onClick={changeColor}>colorfully</button>
</div>
<style jsx>
{
` div{ color:${color};}`
}
</style>
</div>
)
}
8.使用自定義css樣式 、 antd樣式
8.1 使用自定義css樣式
yarn add @zeit/next-css
//先用yarn命令來安裝@zeit/next-css包,它的主要功能就是讓Next.js可以加載CSS文件,有了這個(gè)包才可以進(jìn)行配置。
// 建立一個(gè)next.config.js.這個(gè)就是Next.js的總配置文件 配置如下
const withCss = require('@zeit/next-css')
if(typeof require !== 'undefined'){
require.extensions['.css']=file=>{}
}
module.exports = withCss({})
8.2 使用antd樣式
yarn add antd
yarn add babel-plugin-import
//根目錄建立.babelrc
{
"presets": [
//Next.js的總配置文件,相當(dāng)于繼承了它本身的所有配置
"next/babel"
],
"plugins": [ //增加新的插件,這個(gè)插件就是讓antd可以按需引入,包括CSS
[
"import",
{
"libraryName": "antd",
}
]
]
}
end 打包(完結(jié))
??使用antd樣式打包會(huì)出問題,antd的bug,需要小小的配置一下。
然后就打包就完事 yarn build -> yarn start。不打包不能start。開發(fā)yarn dev 就好了
package.json
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start -p 80"
},
pages 目錄下新建 _app.js文件
import App from 'next/app'
import 'antd/dist/antd.css'
export default App