Next.js的简介
- Next.js 是一个轻量级的React服务器渲染应用框架
- 完善的React项目架构,搭建轻松。比如:Webpack配置,服务器启动,路由配置,缓存能力,这些在它内部已经完善的为我们搭建完成了。
- 自带数据同步策略,解决服务端渲染最大难点。把服务端渲染好的数据,拿到客户端重用,这个在没有框架的时候,是非常复杂和困难的。有了Next.js,它为我们提供了非常好的解决方法,让我们轻松的就可以实现这些步骤。
- 灵活的配置,让开发变的更简单。它提供很多灵活的配置项,可以根据项目要求的不同快速灵活的进行配置。
- 目前Next.js是React服务端渲染的最佳解决方案,所以如果你想使用React来开发需要SEO的应用,基本上就要使用Next.js。
优点
- 有了Next.js以后我们可以简单轻松的实现React的服务端渲染,从而加快首屏打开速度,也可以作SEO(搜索引擎优化了)。
- 在没有Next.js的时候,用React开发需要配置很多繁琐的参数,如Webpack配置,Router配置和服务器端配置等....。
- 如果需要作SEO,要考虑的事情就更多了,怎么样服务端渲染和客户端渲染保持一致就是一件非常麻烦的事情,需要引入很多第三方库。
- 但有了Next.js,这些问题都解决了,使开发人员可以将精力放在业务逻辑上
创建Next.js项目
手动创建
1. npm init // 在根目录里给你添加了一个package.json的文件
2. npm install --save react react-dom next // 安装所需要的依赖包
3. "scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev" : "next" ,
"build" : " next build",
"start" : "next start"
} // 配置package.json,增加快捷命令
4. 创建pages 文件夹(这个文件夹名字是next规定的)next.js 会自动创建对应的路由,创建文件夹后(index.js) 使用/index 即可访问
5. npm run dev // 运行
运行 npm run dev 命令并打开 http://localhost:3000。
如果你想使用其他端口,可运行 npm run dev -- -p <设置端口号>.`npm run dev -- -p 3080`:ready - started server on http://localhost:3080
npm run dev -- -p 3080
> next.js@1.0.0 dev /Users/mavis/gitHub/2020_react/next.js-demo
> next
ready - started server on http://localhost:3080
(node:43465) ExperimentalWarning: The fs.promises API is experimental
event - compiled successfully
create-next-app(脚手架)来创建
npx 是Node自带的npm模块,所以你只要安装了Node都是可以直接使用npx命令的。
1. npm install -g npx// 安装全局next.js
2. npx create-next-app next-create // 创建项目
3. npm run dev // 运行
项目结构介绍
- components 放置公共组建(不包括页面)
- node_modules 依赖包
- pages 这里是放置静态文件的,一些页面,这里的内容会自动生成路由,并在服务端渲染,渲染好后会数据同步
- static 静态文件夹,放一些图片和静态资源
- .gitignore 忽略提交Git上传文件
- package.json 文件的配置信息(名称,版本,许可证)最主要的是用来npm install 下载依赖包
路由-基础和基本跳转
1. Link 和 Router
import React from 'react'
import Link from 'next/link'
import Router from 'next/router'
const Home = () => {
function gotoA() {
Router.push({
pathname: '/IndexB',
query: {
name: 'ldd'
}
})
}
return (
<div>
<div>我是首页</div>
{/* Link链接不支持兄弟标签 */}
<div><Link href="/indexA?name=小白"><a>去IndexA页面</a></Link></div>
<div><button onClick={gotoA}>去IndexB页面</button></div>
</div>
)
}
export default Home
2. 传值和接收参数
接收传递过来的参数 在Next.js中只能通过通过query(?id=1)来传递参数,而不能通过(path:id)的形式传递参数
import Link from 'next/link'
import { withRouter} from 'next/router' // 是next的高阶组件,用来处理路由的
const IndexA = ({router})=>(
<div>
<div>Index-A page. name:{router.query.name}</div>
<Link href="/"><a>返回首页</a></Link>
</div>
)
export default withRouter(IndexA)
3. 路由的六个钩子事件
路由的钩子事件,就是当路由发生改变的时候,可以监听到这些事件, Router.events.on() 用来监听事件
import Router from 'next/router'
import { withRouter} from 'next/router'
const routerChange = ({ router }) => {
Router.events.on('routeChangeStart', (...args) => {
console.log('1.routeChangeStart->路由开始变化,参数为:', ...args)
})
Router.events.on('routeChangeComplete', (...args) => {
console.log('2.routeChangeComplete->路由结束变化,参数为:', ...args)
})
Router.events.on('beforeHistoryChange', (...args) => {
console.log('3.beforeHistoryChange->在改变浏览器 history之前触发,参数为:', ...args)
})
Router.events.on('routeChangeError', (...args) => {
console.log('4.routeChangeError->跳转发生错误,参数为:', ...args)
})
Router.events.on('hashChangeStart', (...args) => {
console.log('5.hashChangeStart->hash跳转开始时执行,参数为:', ...args)
})
Router.events.on('hashChangeComplete', (...args) => {
console.log('6.hashChangeComplete->hash跳转完成时,参数为:', ...args)
})
return (
<div>
routerChange页面<br />
<Link href="/"><a>返回首页</a></Link><br />
<div>
<Link href="#hash"><a>hash</a></Link>
</div>
<div>
<Link href="/indexA?name=ldd"><a>indexA</a></Link>
</div>
</div>
)
}
export default routerChange
使用getInitialProps中的Axios获取数据
Next.js 提供了getInitialProps静态方法来获取数据,不用在componentDidMount中获取数据了,getInitialProps 是Next.js最伟大的发明,它确定了一种Next.js的一种规范,是next.js自己定义的一个新的生命周期,并且在不影响react的生命周期以外的一个扩展方法,getInitialProps 是一个async函数,所以在getInitialProps函数中可以使用await关键字,用同步方式编程异步逻辑
routerChange.getInitialProps = async () => {
const promise = new Promise((resolve) => {
axios('https://www.easy-mock.com/mock/5dc0d5b143ff8e61fd932abe/example/query').then(
(res) => {
console.log('远程数据结果:', res)
resolve(res.data.data)
}
)
})
return await promise
}
使用Style JSX语法和Antd 编写语法
1. style
next.js 是不支持 css的,所以不能用 import来引入,如果要用的话,需要另外配置(b. 会讲解如何配置)
import Link from 'next/link'
import { withRouter } from 'next/router'
const IndexA = ({ router }) => (
<div>
<div className="name">Index-A page . name:{router.query.name}</div>
<p>这是一段文字,很长的一段文字。。。。。</p>
<Link href="/"><a>返回首页</a></Link>
<style jsx>
{
`
.name {
color: red;
}
p {
background: pink;
}
`
}
</style>
</div>
)
export default withRouter(IndexA)
使用Style JSX的话 next.js 会自动给加入一个随机的类名
2. 配置css
1.yarn add @zeit/next-css
2.在根目录下建立一个next.config.js 代码如下,这个是next.js的总配置文件
3.重启代码运行即可
按需加载Ant Design 加载Ant Design在我们打包的时候会把Ant Design的所有包都打包进来,这样就会产生性能问题,让项目加载变的非常慢。这肯定是不行的,现在的目的是只加载项目中用到的模块,这就需要我们用到一个babel-plugin-import文件。安装完成后,在项目根目录建立.babelrc文件
1. yarn add antd
2. yarn add babel-plugin-import
3. 在项目根目录建立.babelrc文件
{
"presets":["next/babel"], // Next.js的总配置文件,相当于继承了它本身的所有配置
"plugins":[ // 增加新的插件,这个插件就是让antd可以按需引入,包括CSS
[
"import",
{
"libraryName":"antd",
"style":"css"
}
]
]
}
这样配置好了以后,webpack就不会默认把整个Ant Design的包都进行打包到生产环境了,而是我们使用那个组件就打包那个组件,同样CSS也是按需打包的。
通过上面的配置,就可以愉快的在Next.js中使用Ant Desgin,让页面变的好看起来。
自定义<Head> 更加友好的SEO操作
1. 方法一:在各个页面上加<Head>
在pages文件下创建个header.js
import React from 'react';
import Head from 'next/head';
const Header = ()=>(
<div>
<Head>
<title>学习Next.js</title>
<meta charSet='utf-8' />
</Head>
<div>Next.js 是一个轻量级的 React 服务端渲染应用框架。</div>
</div>
)
export default Header