React的服务端渲染框架Next.js的简介

374 阅读2分钟

为什么需要使用Next.js

react/vue/angular: 虽然是单页面应用,但是会导致首屏加载过慢,不利于SEO, Next.js 是一个轻量级的 React 服务端渲染应用框架,用服务端渲染(SSR)可以解决以上两个问题。

Next.js的优点

  • 搭建轻松
  • 自带数据同步 SSR
  • 有丰富的插件 自己形成了生态
  • 灵活的配置

Next.js简单的项目搭建

 使用脚手架进行全局安装
 npm install -g create-next-app
 
 创建Next.js的项目
 $ npx create-next-app next-demo //next-demo是项目名
 
 在浏览器中输入http://localhost:3000/ 检测项目是否生成成功

Next.js的项目结构的介绍

每个页面都是 React 组件(核心~)

  • components文件夹: 用来存放公用的或者有专门用途的组件。
  • node_modules文件夹:Next项目的所有依赖包都在这里,一般我们不用修改和编辑这里的内容。
  • pages文件夹:这里是放置页面的,这里边的内容会自动生成路由,并在服务器端渲染,渲染好后进行数据同步。
  • static文件夹: 这个是静态文件夹,比如项目需要的图片、图标、css文件等静态资源都可以放到这里。

Next.js的路由简介

1.路由的跳转
  有两种路由跳转方式
   // ①标签式跳转
   // 小坑勿踩:  {/* link下边只能有一个根元素,不能有并列的兄弟元素, 所以可以用a标签进行包裹 */}
  import Link from 'next/link';
  <Link href="/jspangA"><a>A页面</a></Link>
  
  // ②编程式跳转 耦合性比较低
  import Router from 'next/router'; 
   function testRouterDemo(){
    Router.push({
      pathname: '/test'
    })
  }
  
 2. 路由传参
 // 只能使用query?id = 1进行传参    不支持path:id来传参
 ①<Link href="/test?name=one"><a>标签式</a></Link>
  <Link href={{pathname: '/test', query: {name: 'test'}}}><a>标签式</a></Link>
  
 ② function gotoBlue(){
    Router.push({
      pathname: '/test',
      query: {name: 'one'}
    })
  }
  
  3.路由的接收参数
  使用withRouter组件来进行参数的接收
  import { withRouter} from 'next/router' // 用来接受参数的
  import Link from 'next/link'
  const GetParamCom = ({router})=>{ // 如果不引入withRouter,就没有这个函数里的参数 
        return (
            <>  // 可以使用空标签进行元素的包裹
                <div>{router.query.name},获取地址栏的参数 .</div>
                <Link href="/"><a>返回首页</a></Link>
            </>
        )
    }

export default withRouter(GetParamCom) // withRouter有着路由技能的装备
 
 路由的钩子事件
  // routeChangeStart ==> 路由发生变化之前
  // routeChangeComplete ==> 发生结束变化时
  // beforeHistoryChange ==>  浏览器history触发前
  // routeChangeError ==> 路由跳转发生错误的时候
  // hashChangeStart ==> 转变成hash路由模式开始执行
  // hashChangeComplete ===》转变成hash路由模式完成执行

Next.js的getInitialProps静态方法的介绍

当页面初始化加载时,getInitialProps只会加载在服务端。只有当路由跳转(Link组件跳转或 API 方法跳转)时,客户端才会执行getInitialProps。
我们可以简单的理解getInitialProps是react生命周期的扩充,他是Next.js一个的一个伟大的发明,是实现服务端渲染的重要的方法,Next.js 会调用 getInitialProps 来获取数据,然后把获得数据作为 props 来启动 React 组件的原本生命周期。我们不用关心getInitialProps什么时候被调用,这些都可以交给Next.js来完成。

getInitialProps静态方法是用来获取远端数据,这是这个框架的约定,所以我们要遵循框架的约定,不要试图在生命周期中获取远端的数据。
注意:getInitialProps将不能使用在子组件中。只能使用在pages页面中。

 例子:
 const Test = ({list}) => { //因为在getInitialProps这里请求的远程数据的key是list,所以在这个组件中可以直接使用
  return(
    <>
      <div>{list}</div>
    </>
  )
}

 Test.getInitialProps = async() => { // 因为请求有时差 所以用异步进行操作  
  const promise = new Promise((resolve) => {
    axios('接口请求地址').then(
      (res) => {
        console.log('result:', res);
        resolve(res.data.data); // 获取成功了就告诉resolve,然后把结果返回出去
      }
    )
  })
  return await promise;
}

export default Test; 

getInitialProps的入参对象的简介

  • pathname - URL 的 path 部分
  • query - URL 的 query 部分,并被解析成对象
  • asPath - 显示在浏览器中的实际路径(包含查询部分),为String类型
  • req - HTTP 请求对象 (只有服务器端有)
  • res - HTTP 返回对象 (只有服务器端有)
  • jsonPageRes - 获取数据响应对象 (只有客户端有)
  • err - 渲染过程中的任何错误
eg.
 Test.getInitialProps = async( { pathname } ) => { 
  const promise = new Promise((resolve) => {
    axios('接口请求地址').then(
      (res) => {
        console.log(pathname) // 可以帮助获取URL的path部分
      }
    )
  })
  return await promise;
}
 

使用style jsx来进行编写css样式

加入了Style jsx代码后,Next.js会自动加入一个随机类名,这样就防止了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>
       {/* 动态的css样式 */}
      <style jsx>
        {`
          div{color: ${color}}
          .test{color: red;}
        `}
      </style>
    </>
  )
}

export default Style;

模块的懒加载

  • 懒加载模块(react中模块的理解一般是指的外部库)
  • 一般使用懒加载的场景:不是主要的业务逻辑,所以不用及时去加载这些外部库 所以使用懒加载
我们以外部的moment库作为模板进行测试

import React, {useState}  from 'react';

function Time(){
  const [time, SetTime] = useState(Date.now());
  const formatTime = async() => {
    const moment = await import('moment'); // ① 引入的时候是需要时间的,所以这些外部库 在需要的时候再进入
    SetTime(moment.default(Date.now()).format())
  }

  return (
    <>
     <div>显示时间为: {time}</div>
     <button onClick={formatTime}>改变时间格式</button> // 点击的时候才会去调用外部模块
    </>
  )
}

export default Time;

  • 懒加载自定义组件
import React, {useState}  from 'react';
import dynamic from 'next/dynamic'; // 用来懒加载组件

const CustomCom = dynamic(import('../components/customCom')); // ②只有执行到渲染CustomCom的时候才会加载进来,控制台可以看出来

function CustomComponent(){
  return (
    <>
     <CustomCom></CustomCom>
    </>
  )
}

export default CustomComponent;

如何在Next.js中使用Ant-design UI框架

首要问题是解决Next.js对css的支持问题:

 1. npm install --save @zeit/next-css // 添加相应的包 实现对css的支持
 
 2. 在项目的根目录下创建next.config.js进行相关的配置(配置内容如下)
 
    const withCss = require('@zeit/next-css')
    if(typeof require !== 'undefined'){
        require.extensions['.css']=file=>{}
    }
    
    module.exports = withCss({})
3.重启一下服务,就可以实现在Next中编写css文件了  是不是很开心哇~

按需加载Ant的模块

1. npm install --save babel-plugin-import

2. 安装完成后,在项目根目录建立.babelrc文件,然后写入如下配置文件。

{
    "presets":["next/babel"],  //Next.js的总配置文件,相当于继承了它本身的所有配置
    "plugins":[     //增加新的插件,这个插件就是让antd可以按需引入,包括CSS
        [
            "import",
            {
                "libraryName":"antd",
                "style":"css"
            }
        ]
    ]
}

总结

希望这点简单的介绍 可以给需要的小伙伴带来一点帮助哈~😊