next.js简介
最近在学React.js,React官方推荐使用next.js框架作为构建服务端渲染的网站,所以今天来写一些Demo( Github地址)研究一下next.js的使用。
next.js作为一款轻量级的应用框架,主要用于构建静态网站和后端渲染网站。
框架特点
- 使用后端渲染
- 自动进行代码分割(code splitting),以获得更快的网页加载速度
- 简洁的前端路由实现
- 使用webpack进行构建,支持模块热更新(Hot Module Replacement)
- 可与主流Node服务器进行对接(如express)
- 可自定义babel和webpack的配置
使用方法
创建项目并初始化
mkdir server-rendered-website
cd server-rendered-website
npm init -y
安装next.js
使用npm或者yarn安装,因为是创建React应用,所以同时安装react和react-dom
npm:
npm install --save react react-dom next
yarn:
yarn add react react-dom next
在项目根目录下添加文件夹pages(一定要命名为pages,这是next的强制约定,不然会导致找不到页面),然后在package.json文件里面添加script用于启动项目:
"scripts": {
"dev": "next"
}
如下图
创建视图
在pages文件夹下创建index.js文件,文件内容:
const Index = () => (
<div>
<p>Hello next.js</p>
</div>
)
export default Index
运行
npm run next
在浏览器中打开http://localhost:3000/,网页显示如下:
这样就完成了一个最简单的next网站。
前端路由
next.js前端路由的使用方式非常简单,我们先增加一个page,叫about,内容如下:
const About = () => (
<div>
<p>This is About page</p>
</div>
)
export default About;
当我们在浏览器中请求https://localhost:3000/about时,可以看到页面展示对应内容。(==这里需要注意:请求url的path必须和page的文件名大小写一致才能访问,如果访问localhost:3000/About的话是找不到about页面的。==)
我们可以使用传统的a标签在页面之间进行跳转,但每跳转一次,都需要去服务端请求一次。为了增加页面的访问速度,推荐使用next.js的前端路由机制进行跳转。
next.js使用next/link实现页面之间的跳转,用法如下:
import Link from 'next/link'
const Index = () => (
<div>
<Link href="/about">
<a>About Page</a>
</Link>
<p>Hello next.js</p>
</div>
)
export default Index
这样点击index页面的AboutPage链接就能跳转到about页面,而点击浏览器的返回按钮也是通过前端路由进行跳转的。 官方文档说用前端路由跳转是不会有网络请求的,实际会有一个对about.js文件的请求,而这个请求来自于页面内动态插入的script标签。但是about.js只会请求一次,之后再访问是不会请求的,毕竟相同的script标签是不会重复插入的。 但是想比于后端路由还是大大节省了请求次数和网络流量。前端路由和后端路由的请求对比如下:
前端路由:
后端路由:
Link标签支持任意react组件作为其子元素,不一定要用a标签,只要该子元素能响应onClick事件,就像下面这样:
<Link href="/about">
<div>Go about page</div>
</Link>
Link标签不支持添加style和className等属性,如果要给链接增加样式,需要在子元素上添加:
<Link href="/about">
<a className="about-link" style={
{
color:'#ff0000'}}>Go about page</a>
</Link>
Layout
所谓的layout就是就是给不同的页面添加相同的header,footer,navbar等通用的部分,同时又不需要写重复的代码。在next.js中可以通过共享某些组件实现layout。
我们先增加一个公共的header组件,放在根目录的components文件夹下面(页面级的组件放pages中,公共组件放components中):
import Link from 'next/link';
const linkStyle = {
marginRight: 15
}
const Header = () => (
<div>
<Link href="/">
<a style={linkStyle}>Home</a>
</Link>
<Link href="/about"&g