为什么需要使用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"
}
]
]
}
总结
希望这点简单的介绍 可以给需要的小伙伴带来一点帮助哈~😊
网友评论