Next.js
Next.js 是一个轻量级的 React 服务端渲染应用框架。有了它我们可以简单轻松的实现React的服务端渲染,从而加快首屏打开速度,也可以作SEO(收索引擎优化了)。在没有Next.js的时候,用React开发需要配置很多繁琐的参数,如Webpack配置,Router配置和服务器端配置等….。如果需要作SEO,要考虑的事情就更多了,怎么样服务端渲染和客户端渲染保持一致就是一件非常麻烦的事情,需要引入很多第三方库。但有了Next.js,这些问题都解决了,使开发人员可以将精力放在业务逻辑上,从繁琐的配置中解放出来。
简介
Next.js 是一个轻量级的 React 服务端渲染应用框架。
用一个框架,就要知道它的优点(或者是解决了我们什么问题):
- 完善的React项目架构,搭建轻松。比如:Webpack配置,服务器启动,路由配置,缓存能力,这些在它内部已经完善的为我们搭建完成了。
- 自带数据同步策略,解决服务端渲染最大难点。把服务端渲染好的数据,拿到客户端重用,这个在没有框架的时候,是非常复杂和困难的。有了Next.js,它为我们提供了非常好的解决方法,让我们轻松的就可以实现这些步骤。
- 丰富的插件帮开发人员增加各种功能。每个项目的需求都是不一样的,包罗万象。无所不有,它为我们提供了插件机制,让我们可以在使用的时候按需使用。你也可以自己写一个插件,让别人来使用。
- 灵活的配置,让开发变的更简单。它提供很多灵活的配置项,可以根据项目要求的不同快速灵活的进行配置。
目前Next.js是React服务端渲染的最佳解决方案,所以如果想使用React来开发需要SEO的应用,基本上就要使用Next.js。
create-next-app 快速创建Next.js项目
项目结构介绍:
- components文件夹:这里是专门放置自己写的组件的,这里的组件不包括页面,指公用的或者有专门用途的组件。
- node_modules文件夹:Next项目的所有依赖包都在这里,一般我们不会修改和编辑这里的内容。
- pages文件夹:这里是放置页面的,这里边的内容会自动生成路由,并在服务器端渲染,渲染好后进行数据同步。
- public文件夹: 这个是静态文件夹,比如项目需要的图片、图标和静态资源都可以放到这里。
- .gitignore文件: 这个主要是控制git提交和上传文件的,简称就是忽略提交。
- package.json文件:定义了项目所需要的文件和项目的配置信息(名称、版本和许可证),最主要的是使用
npm install
就可以下载项目所需要的所有包。
Page和Component的使用
直接在pages文件夹下,新建一个xxx.js
页面,写好相应的代码后,Next
框架就自动做好了路由。如果要做更深的路由,在pages文件夹下再建相应的文件夹,然后在新的文件夹里面新建页面,以此类推即可。
pages里面的文件名和components文件夹里面的文件名可以相同,不会冲突。
在components文件夹目录新建组件,在pages里面引入即可。
路由-基础和基本跳转
路由跳转两种形式:
标签式导航:利用标签
<Link>
引入:
import Link from 'next/link'
使用:
<Link href="/"><a>返回首页</a></Link>
注意:不写
<a>
标签时不支持兄弟标签并列,使用<a>
便可使用1
2
3
4
5
6<Link href="/jspangA">
<a>
<span>去JspangA页面</span>
<span>前端博客</span>
</a>
</Link>编程式跳转:用js编程的方式进行跳转,也就是利用
Router
组件引入:
import Router from 'next/router'
使用:
<button onClick={()=>{Router.push('/jspangA')}}>去JspangA页面</button>
这种写法简单,但是耦合性太高,可以修改一下 ,把跳转放到一个方法里,然后调用方法。1
2
3
4
5function gotoA(){
Router.push('/jspangA')
}
<button onClick={gotoA}>去JspangA页面</button>
路由-跳转时用query传递和接收参数
项目开发中一般需要动态跳转,动态跳转就是跳转时需要带一个参数或几个参数过去,然后在到达的页面接受这个传递的参数,并根据参数不同显示不同的内容。比如新闻列表,然后点击一个要看的新闻就会跳转到具体内容。这些类似这样的需求都都是通过传递参数实现的。
只能用query传递参数:在Next.js
中只能通过通过query(?id=1
)来传递参数,而不能通过(path:id
)的形式传递参数。
标签式导航传递参数:
1 | <Link href="/jpangA?name=技胖"><a>技胖</a></Link> |
这种写法有两个参数,一个是pathname
,一个是query
,query
里面包含传递的参数
编程式跳转传递参数:
1 | function gotojpang(){ |
或者:
1 | function gotojpang(){ |
接受参数:withRouter
是Next.js框架的高级组件,用来处理路由用的
1 | //①引入withRouter |
路由-六个钩子事件
路由的钩子事件,也就是当路由发生变化时,可以监听到这些变化事件,执行对应的函数。利用钩子事件是可以作很多事情的,比如转换时的加载动画,关掉页面的一些资源计数器…..
routerChangeStart
路由发生变化时使用Router组件,然后用
on
方法来进行兼听routerChangeComplete
路由结束变化时beforeHistoryChange
浏览器history触发前history就是HTMP中的API,
Next.js
路由变化默认都是通过history进行的,所以每次都会调用。 不适用history的话,也可以通过hash。正确顺序为:①③②
routeChangeError
路由跳转发生错误时注意:404找不到路由页面不算错误
转变成hash路由模式
以下两种事件都是针对hash的。
hashChangeStart
:hash跳转开始时执行hashChangeComplete
:hash跳转完成时执行
1 | import React from 'react' |
在getInitialProps中使用Axios获取远端数据
在Next.js
框架中提供了getInitialProps
静态方法用来获取远端数据,这个是框架的约定,所以你也只能在这个方法里获取远端数据。不要在生命周期里面获得,虽然可以,但是不符合约定。
安装axios: yarn add axios
引入: import axios from 'axios'
获取数据例子:
1 | //使用getInitialProps远程获取数据 |
使用Style JSX编写页面的CSS样式
在Next.js
中引入一个CSS样式是不可以用的,如果想用,需要作额外的配置。因为框架为我们提供了一个style jsx
特性,也就是把CSS用JSX的语法写出来。
一个特性:自动添加随机类名,不会污染全局css—加入了Style jsx
代码后,Next.js
会自动加入一个随机类名,这样就防止了CSS的全局污染。比如我们把代码写成下面这样,然后在浏览器的控制台中进行查看,你会发现自动给我们加入了类名,类似jsx-xxxxxxxx
例如:
1 | function Jspang(){ |
动态显示样式:
比如:
1 | import React, {useState} from 'react' |
Lazy Loading实现模块懒加载
当项目越来越大的时候,模块的加载是需要管理的,如果不管理会出现首次打开过慢,页面长时间没有反应一系列问题。这时候可用Next.js
提供的LazyLoading
来解决这类问题。让模块和组件只有在用到的时候在进行加载,一般我把这种东西叫做“懒加载”.它一般分为两种情况,一种是懒加载(或者说是异步加载)模块,另一种是异步加载组件。
当我们作的应用存在首页打开过慢和某个页面加载过慢时,就可以采用
Lazy Loading
的形式,用懒加载解决这些问题。
懒加载模块:
比如我们引入开发中常用的模块Moment.js
,它是一个JavaScript日期处理类库。安装:yarn add moment
。
例如(未使用懒加载):
1 | import React, {useState} from 'react' |
这个看起来很简单和清晰的案例,缺存在着一个潜在的风险,就是如何有半数以上页面使用了这个momnet
的库,那它就会以公共库的形式进行打包发布,就算项目第一个页面不使用moment
也会进行加载,这就是资源浪费,对于我这样有代码洁癖的良好程序员是绝对不允许的。下面我们就通过Lazy Loading
来进行改造代码。
改良(使用懒加载):
1 | import React, {useState} from 'react' |
懒加载自定义组件
首先要在懒加载这个组件的文件汇总引入dynamic
,import dynamic from 'next/dynamic'
使用:
1 | import dynamic from 'next/dynamic' //引入dynamic |
写完代码后,可以看到自定义组件是懒加载的,只有在jsx
里用到``时,才会被加载进来,如果不使用就不会被加载。
自定义Head更加友好的SEO操作
定制<Head>
标签
方法一:在各个页面加上
<Head>
标签(推荐)例如在pages中的某一个页面:
1
2
3
4
5
6
7
8
9
10
11
12
13
14import Head from 'next/head' //引入Head
function Header(){
return (
<>
//使用Head
<Head>
<title>技术胖是最胖的!</title>
<meta charSet='utf-8' />
</Head>
<div>JSPang.com</div>
</>
)
}
export default Header方法二:定义全局的
<Head>
这种方法相当于自定义了一个组件,然后把在组件里定义好,以后每个页面都使用这个组件,其实这种方法用处不大,也不灵活。因为
Next.js
已经把<Head>
封装好了,本身就是一个组件,我们再次封装的意义不大。
Next.js框架下使用Ant Design UI
让Next.js支持CSS文件:
安装@zeit/next-css
包,它的主要功能就是让Next.js
可以加载CSS文件,有了这个包才可以进行配置:yarn add @zeit/next-css
配置:建立一个next.config.js
(建在最外面的那个目录)这个就是Next.js
的总配置文件。
1 | const withCss = require('@zeit/next-css') |
按需加载Ant Design
加载Ant Design
在我们打包的时候会把Ant Design
的所有包都打包进来,这样就会产生性能问题,让项目加载变的非常慢。这肯定是不行的,现在的目的是只加载项目中用到的模块,这就需要我们用到一个babel-plugin-import
文件。
先安装Ant Design
库:yarn add antd
安装babel-plugin-import
插件:yarn add babel-plugin-import
配置babel-plugin-import
插件:在项目根目录建立.babelrc
文件,然后写入如下配置文件。
1 | { //Next.js的总配置文件,相当于继承了它本身的所有配置 |
配置好了以后,webpack
就不会默认把整个Ant Design
的包都进行打包到生产环境了,而是我们使用那个组件就打包那个组件,同样CSS也是按需打包的。
使用:
1 | import {Button} from 'antc' |
Next.js生产环境打包
其实Next.js大打包时非常简单的,只要一个命令就可以打包成功。但是当你使用了Ant Desgin
后,在打包的时候会遇到一些坑。
打包 :next build
运行:next start -p 80
先把这两个命令配置到package.json
文件里,比如配置成下面的样子。
1 | "scripts": { |
然后在终端里运行一下yarn build
,如果这时候报错,其实是我们在加入Ant Design
的样式时产生的,你可以改用全局引入CSS解决问题。
在page目录下,新建一个_app.js
文件,然后写入下面的代码。
1 | import App from 'next/app' |
这样配置一下,就可以打包成功了,然后再运行yarn start
来运行服务器,看一下我们的header
页面,也是有样式的。说明打包已经成功了。