React的服務(wù)端渲染框架Next.js的簡(jiǎn)介

為什么需要使用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)幫助哈~??

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容