书接上文 Next.js 使用指南1-基本规则,这节我们将过渡到一些高级的功能。涉及到的内容包含:路由、高阶组件、预加载、动态路由等等,快来开始吧!
一、路由拦截
1 | import Router from 'next/router' |
Router
有如下的属性和方法,我们可以根据实际情况来使用:
- route - 返回当前路由
- pathname - 返回当前路径包含 query 部分
- query - 返回 query 对象,默认为 {}
- asPath - 浏览器中的实际路径,包含 query 部分
- push(url, as=url) - performs a pushState call with the given url
- replace(url, as=url) - performs a replaceState call with the given url
- beforePopState(cb=function) - intercept popstate before router processes the event.
二、路由事件
为了满足更多的业务场景,我们可能需要监听路由事件,这时候,有一些事件是可以用的:
- onRouteChangeStart(url) - Fires when a route starts to change
- onRouteChangeComplete(url) - Fires when a route changed completely
- onRouteChangeError(err, url) - Fires when there’s an error when changing routes
- onBeforeHistoryChange(url) - Fires just before changing the browser’s history
1 | Router.onRouteChangeStart = url => { |
如果不需要监听了,请释放它:
1 | Router.onRouteChangeStart = null |
如果路由载入取消,就会触发routeChangeError
,参数 err
的属性 cancelled
就被设置成了 true
1 | Router.onRouteChangeError = (err, url) => { |
三、浅路由模式
所谓浅路由模式,其实就是不再初始化 getInitalProps
,但是我们依然可以得到更新的 pathname
和 query
。使用方法如下:
1 | // Current URL is "/" |
更多的使用场景,可能类似与分页数据,我们只改变 page
,而不需要整个初始化。当然,我们可以监听:
1 | componentWillReceiveProps(nextProps) { |
需要注意的是:浅路由模式只支持相同的 URL,如果页面路由变化,还是会触发 getInitialProps。
四、使用高阶组件
1 | import { withRouter } from 'next/router' |
这时候,router 中就会有我们需要的所有参数,使用起来还是蛮方便的。
五、预加载页面
通过预取 Next.js
只下载 JS
代码,当页面开始渲染,可能需要等待数据。
1 | import Link from 'next/link' |
当然,这并不是预加载的妙用,真正的作用请看下面的例子:
1 | import Router from 'next/router' |
我们即将跳转 dynamic
,可以进行预加载。
六、禁用默认路由
如果想禁用默认路由,需要添加文件 next.config.js
,并增加配置:
1 | // next.config.js |
七、动态前缀
动态修改路径前缀,适合有 CDN
配置的静态资源部署:
1 | const next = require('next') |
八、动态引入
简单用法:
1
2
3
4
5
6
7
8
9import dynamic from 'next/dynamic'
const DynamicComponent = dynamic(import(‘./jartto'))
export default () =>
<div>
<DynamicComponent />
<p>HOME PAGE is here!</p>
</div>增加自定义组件
1
2
3
4
5
6
7
8
9
10
11
12
13
14import dynamic from 'next/dynamic'
const DynamicComponentWithCustomLoading = dynamic(
import('../components/jartto'),
{
loading: () => <p>...</p>
}
)
export default () =>
<div>
<DynamicComponentWithCustomLoading />
<p>HOME PAGE is here!</p>
</div>禁止服务端渲染
1
2
3
4
5
6
7
8
9
10
11import dynamic from 'next/dynamic'
const DynamicComponentWithNoSSR = dynamic(import('./image'), {
ssr: false
})
export default () =>
<div>
<DynamicComponentWithNoSSR />
<p>Hello Jartto!</p>
</div>加载多个模块
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24import dynamic from 'next/dynamic'
const HelloBundle = dynamic({
modules: props => {
const components = {
Hello1: import('../components/jartto1'),
Hello2: import('../components/jartto2')
}
// Add remove components based on props
return components
},
render: (props, { Hello1, Hello2 }) =>
<div>
<h1>
{props.title}
</h1>
<Hello1 />
<Hello2 />
</div>
})
export default () => <HelloBundle title="Dynamic Bundle" />
九、自定义
在 Next.js
使用 App
组件来初始化页面,当然,我们也可以覆写它,从而控制页面的初始化。具体实例如下:
- 在页面变化之间保持布局
- 浏览页面时保持状态
- 自定义异常处理
- 注入附加数据
1 | import App, {Container} from 'next/app' |
注意,我们需要创建 ./pages/_app.js,来覆写 App 类。需要重启服务才能生效!
十、总结
这节内容主要集中在路由和加载方面,如果我们需要更大的控制权,应该会用到高级配置。请查看:Next.js 使用指南3-高级配置。