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

为什么需要使用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"
            }
        ]
    ]
}

总结

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容