跟文档学习next.js
前言:Next.js 是一个轻量级的 React 服务端渲染应用框架。
新建文件夹安装它:
npm install --save next react react-dom
将下面脚本添加到 package.json 中:
{
"scripts": {
"dev": "next",
"build": "next build",
"start": "next start"
}
}
这里注意。启动项目服务后,react默认的端口号是3000,而next的入口文件默认是隐藏的,这点后面再说。所以如果你有项目端口已经用3000的端口号,那么可以修改package.json 中的脚本:
{
"scripts": {
"dev": "next -p 2019",
"build": "next build",
"start": "next start"
}
}
如上,在dev后面添加“-p 端口号”即可;
由于Next.js 只支持React 16,我们使用 React 16 的特性,所以不得不放弃对 React 15 以及以下版本的支持。
Next.js 具有以下几点特性:
- 默认支持服务端渲染
- 自动根据页面进行代码分割
- 简洁的客户端路由方案(基于页面
- 基于 Webpack 的开发环境,支持热模块替换
- 可以跟 Express 或者其它 Node.js 服务器完美集成
- 支持 Babel 和 Webpack 的配置项定制
- 文件系统是主要的 API. 每个.js 文件将变成一个路由,自动处理和渲染。
- 以pages文件作为服务端的渲染和索引
- 热加载
- 静态文件服务.
./static/映射到/static/(可以 创建一个静态项目文件夹在你的项目中,里面放置一些图片和字体等)
继续:新建 ./pages/index.js 到你的项目中;


在我们的项目中,肯定不止一个项目的。那么我们就需要在多个页面之间进行跳转,就要借助next/link组件,下面我们新增一个页面game页面并将index页面进行改写;



game页面


Link标签支持任意react组件作为其子元素,不一定要用a标签,只要该子元素能响应onClick事件,Link标签不支持添加style和className等属性,如果要给链接增加样式,需要在子元素上添加;
由于next支持热加载,所以直接保存就可以看到效果哦;
现在已经可以正常跳转了,那么就需要传递参数了,如果需要给路由传参数,则使用query string的形式:
static async getInitialProps ({ req }) {
const userAgent = req ? req.headers['user-agent'] : navigator.userAgent
return { userAgent }
}
render () {
return (
<div className="app-box">
<p>我是next.js页面</p>
<Link href="/game?title=hello">
<a>To Game Page</a>
</Link>
<p>{this.props.userAgent}</p>
</div>
)
}
static async getInitialProps ({ req, query }) {
const userAgent = req ? req.headers['user-agent'] : navigator.userAgent
return { userAgent, query }
}
render () {
console.log(this.props.query);
return (
<div className="game-box">
<p>我是game页面</p>
<Link href="/">
<a>To index Page</a>
</Link>
<p>{this.props.query.title}</p>
</div>
)
}
从上面两段代码可以看到:
- 当页面渲染时加载数据,我们使用了一个异步方法getInitialProps。它能异步获取 JS 普通对象,并绑定在props上;
- 当服务渲染时,
getInitialProps将会把数据序列化,就像JSON.stringify。所以确保getInitialProps返回的是一个普通 JS 对象,而不是Date,Map或Set类型; - 当页面初次加载时,
getInitialProps只会在服务端执行一次。getInitialProps只有在路由切换的时候(如Link组件跳转或路由自定义跳转)时,客户端的才会被执行; - 当页面初始化加载时,
getInitialProps只会加载在服务端。只有当路由跳转(Link组件跳转或 API 方法跳转)时,客户端才会执行getInitialProps; - 注意:
getInitialProps将不能使用在子组件中。只能使用在pages页面中。
getInitialProps入参对象的属性如下:
pathname:URL 的 path 部分;query: URL 的 query 部分,并被解析成对象;asPath: 显示在浏览器中的实际路径(包含查询部分),为String类型;req: HTTP 请求对象 (只有服务器端有);res: HTTP 返回对象 (只有服务器端有);jsonPageRes:获取数据响应对象(只有客户端有);err: 渲染过程中的任何错误;
当然除了上面的Link跳转之外,还可以通过事件跳转,那么就需要借助next/router实现客户端路由切换:
import Router from 'next/router' export default () =>
<div>
Click <span onClick={() => Router.push('/game')}>here</span> to read more
</div>
这个Router对象的 API 如下:
route: 当前路由的String类型;pathname: 不包含查询内容的当前路径,为String类型;query: 查询内容,被解析成Object类型. 默认为{};asPath: 展现在浏览器上的实际路径,包含查询内容,为String类型;push(url, as=url): 页面渲染第一个参数 url 的页面,浏览器栏显示的是第二个参数 url;replace(url, as=url): performs areplaceStatecall with the given url;beforePopState(cb=function): 在路由器处理事件之前拦截;
注意:Router.beforePopState() 截断Router操作的设置只有在客户端生效(需在componentDidMount中设置)且进入此函数中的方法只有Router栈中有值的时候才可以!
push 和 replace 函数的第二个参数as,是为了装饰 URL 作用。如果你在服务器端设置了自定义路由将会起作用;
ok,通过上面的了解,我们已经学会了页面跳转的几种方式,既然可以跳转,那么可以监听跳转吗?即路由事件:
监听路由相关事件。 下面是事件支持列表:
routeChangeStart(url)--- 路由开始切换时触发routeChangeComplete(url)--- 完成路由切换时触发routeChangeError(err, url)--- 路由切换报错时触发beforeHistoryChange(url)--- 浏览器 history 模式开始切换时触发hashChangeStart(url)--- 开始切换 hash 值但是没有切换页面路由时触发hashChangeComplete(url)--- 完成切换 hash 值但是没有切换页面路由时触发
我们尝试调用路由开始切换的事件:routeChangeStart
// 监听路由开始切换时触发
static onListenRouteChangeStart = () => {
Router.events.on('routeChangeStart', (url) => {
console.log('routerUrl' + url);
});
} componentDidMount () {
RouterApi.onListenRouteChangeStart();
}
如果不需要监听了,请释放它:Router.onRouteChangeStart = null;
既然都聊都了路由这块,那么就说说路由的另一个概念:浅层路由;
所谓浅路由模式,其实就是浅层路由允许你改变 URL 但是不执行getInitialProps生命周期。你可以加载相同页面的 URL,得到更新后的路由属性pathname和query,并不失去 state 状态。
你可以给Router.push 或 Router.replace方法加如:shallow: true参数。如下面的例子所示:
const href = '/?counter=10'
const as = href
Router.push(href, as, { shallow: true });
现在 URL 更新为/?counter=10。在组件里查看this.props.router.query你将会看到更新的 URL。
!需要注意的是:浅路由模式只支持相同的 URL,如果页面路由变化,还是会触发 getInitialProps;
更多的使用场景,可能类似与分页数据,我们只改变 page ,而不需要整个初始化。当然,我们可以监听:
componentWillReceiveProps(nextProps) {
const { pathname, query } = nextProps.url
// fetch data based on the new query
}
你可以在componentdidupdate钩子函数中监听 URL 的变化:
componentDidUpdate(prevProps) {
const { pathname, query } = this.props.router
// verify props have changed to avoid an infinite loop
if (query.id !== prevProps.router.query.id) {
// fetch data based on the new query
}
}
对于路由的一些基本情况如上了,有具体问题具体分析;
那么下面我们来练习一下高阶组件:如果你想应用里每个组件都处理路由对象,你可以使用withRouter高阶组件。下面是如何使用它;
import React, { Component } from 'react';
import { withRouter } from 'next/router'
class RedEnvelope extends Component {
render () {
return (
<div className="envelope-box">
<p>我是红包组件</p>
<h1>{this.props.router.query.title}</h1>
</div>
)
}
}
export default withRouter(RedEnvelope);
我在game页面调用这个组件里面调用到this.props.router这个对象了:

ok,了解这些,就开始写项目吧,后面的配置和部署,接下来再更新
跟文档学习next.js的更多相关文章
- EasyUI文档学习心得
概述 jQuery EasyUI 是一组基于jQuery 的UI 插件集合,它可以让开发者在几乎完全不需要CSS以及复杂的JS代码情况下完成美观且功能强大的Web界面. 本文主要说明一些如何利用Eas ...
- jquery.cookie 使用文档,$.cookie() 文档教程, js 操作 cookie 教程文档。
jquery.cookie 使用文档,$.cookie() 文档教程, js 操作 cookie 教程文档. jquery.cookie中的操作: jquery.cookie.js是一个基于jquer ...
- Spring文档学习
Spring文档学习 参考Spring Framework Documentation学习 1. IoC 容器 1.1 容器实例化 <beans> <import resource= ...
- 通过程序校验xml文档学习笔记
校验xml文档,可以通过程序来校验,利用一段js代码即可. 各行代码的含义已经写出,运行这个html文件,检验如下xml代码: 结果如下: 如果xml文档出现错误: 结果如下: 其中,obj.asyn ...
- Cassandra1.2文档学习解读计划——为自己鼓劲
最近想深入研究一下Cassandra,而Cassandra没有中文文档,仅有的一些参考书都是0.7/0.6版本的.因此有个计划,一边学习文档(地址:http://www.datastax.com/do ...
- Nodejs v4.x.0API文档学习(2)Assert断言测试模块
文档参考地址:https://nodejs.org/dist/latest-v4.x/docs/api/ Assert(断言) assert模块提供了一组简单的断言测试方法,可以拥有测试不变量.该模块 ...
- Nodejs v4.x.0API文档学习(1)简介
文档参考地址:https://nodejs.org/dist/latest-v4.x/docs/api/ 简介 下面是用nodejs编写的一个web服务的例子,返回"Hello World& ...
- jQuery 源码分析和使用心得 - 文档遍历 ( traversing.js )
jQuery之所以这么好用, 首先一点就是$()方法和它强大的选择器. 其中选择器使用的是sizzle引擎, sizzle是jQuery的子项目, 提供高效的选择器查询. 有个好消息告诉大家, 就是s ...
- 《MATLAB从入门到放弃》二维曲线和图形绘制基础(二):使用Help文档学习line、plot、plotyy、subplot、hold绘图函数
目录: » plot 最常用的二维曲线绘图函数 > 帮助文档 > 基本使用语法 > 线条的样式.符号和颜色调整 > 图形属性调整 > 使用图形句柄进行设置 » ...
随机推荐
- nginx安装错误:c compiler cc is not found
今天安装软件nginx的时候遇到的报错:c compiler cc is not found 查了下网上的资料,解决方案也不复杂. 先说明下环境: 服务器:CentOS 7 nginx:2.3.1 原 ...
- xcode简介及安装
1. 简介 Xcode 是运行在操作系统Mac OS X上的集成开发工具(IDE),由苹果公司开发. Xcode是开发OS X 和 iOS 应用程序的最快捷的方式. Xcode 具有统一的用户界面设计 ...
- CodeForces 375D Tree and Queries 莫队||DFS序
Tree and Queries 题意:有一颗以1号节点为根的树,每一个节点有一个自己的颜色,求出节点v的子数上颜色出现次数>=k的颜色种类. 题解:使用莫队处理这个问题,将树转变成DFS序区间 ...
- Go组件学习——手写连接池并没有那么简单
1.背景 前段时间在看gorm,发现gorm是复用database/sql的连接池. 于是翻了下database/sql的数据库连接池的代码实现,看完代码,好像也不是很复杂,但是总觉得理解不够深刻,于 ...
- webstorm的live templates快速编辑功能,让你的css JS代码书写速度飞起来
前言: Emmet的前身是大名鼎鼎的Zen coding,如果你从事Web前端开发的话,对该插件一定不会陌生.它使用仿CSS选择器的语法来生成代码, 大大提高了HTML/CSS代码编写的速度,比如下面 ...
- CCPC-Wannafly Summer Camp #1(部分解题报告)
A:Birthday 时间限制: 1 Sec 内存限制: 256 MB 题目描述 恬恬的生日临近了.宇扬给她准备了一个大蛋糕. 正如往常一样,宇扬在蛋糕上插了n支蜡烛,并把蛋糕分为m个区域.因为某种 ...
- odoo12从零开始:三、2)odoo模型层
前言 上一篇文章(创建你的第一个应用模块(module))已经大致描述了odoo的模型层(model)和视图层(view),这一篇文章,我们将系统地介绍有关于model的知识,其中包括: 1.模型的类 ...
- ReentrantLock分析
主要分析下ReentrantLock锁的占用和释放过程. 一.几个核心变量 AbstractOwnableSynchronizer{ /** * 表示当前占有独占锁的线程,为null时说明锁未被占用 ...
- Vue 利用指令实现禁止反复发送请求
前端做后台管控系统,在某些接口请求时间过长的场景下,需要防止用户反复发起请求. 假设某场景下用户点击查询按钮后,后端响应需要长时间才能返回数据.那么要规避用户返回点击查询按钮无外乎是让用户无法在合理时 ...
- 腾讯工作近十年大佬:不是我打击你!你可能真的不会写Java
文章核心 其实,本不想把标题写的那么恐怖,只是发现很多人干了几年 Java 以后,都自认为是一个不错的 Java 程序员了,可以拿着上万的工资都处宣扬自己了,写这篇文章的目的并不是嘲讽和我一样做 Ja ...