next.js koa 笔记
nextjs 是自身带有服务器,但它这个服务器只是用于处理 ssr 服务器渲染。像 http 请求数据,数据库连接、session 状态这些操作 nextjs 的这个服务都不处理,所以需要使用 koa 等类似的服务,手动来处理。
运行
1 | node server.js |
next 默认不支持 css 文件
从服务端原理讲解课程中了解到,
style-loader
无法把css
挂载到页面上,因为服务端渲染不生成html
文件,所以即使生成了css
文件,也没地方挂,服务端返回的直接是 html 字符串。所以需要使用isomorphic-style-loader
,使用这个loader
,在组件中可以以对象的方式获取到引用的css
,然后把css
内容放到context
的全局对象中,在返回html
内容时把全局中的 css 字符串都拼接好,然后拼到html
字符串中。
添加 nextjs 的配置文件,在根目录创建next.config.js
,使用官网推荐的@zeit/next-css
安装:
1 | npm i @zeit/next-css |
在配置文件中添加
1 | const withCss = require("@zeit/next-css"); |
这样就可以在组件中import css
文件了,并且生成的是 css 的 chunk 文件并在文件中引用,而不像 style-loader 那样是把 css 内容直接插进 html 中。
使用 antd
安装
1 | npm i and --save |
###配置 antd 的按需加载
官网推荐了两种方式,一种是使用babel-import-plugin
,
1 | // .babelrc or babel-loader option |
一种是使用绝对路径来引入每个组件
1 | import DatePicker from 'antd/es/date-picker'; // 加载 JS |
第一种使用方便,使用第一种方式,打包的时候,babel 会转换成第二种,所以推荐第一种。
解决 antd 样式问题
上面的标注写了,无法配置样式的引入,所以需要在手动来处理。
###_app.js_app.js
是覆盖 nextjs 默认 app 组件的地方。
在 pages 文件夹中新建_app.js
文件
1 | import App from "next/app"; |
这样 andt 的组件就有样式了。
###前端路由跳转
1 | import Link from 'next/link' |
Link 本身是没有标签的(可以 F12 查看),所以需要指定渲染的内容,必须给它传递一个有 onclick 的组件,Link 就是给他的子组件绑定 click 事件,click 事件跳转到指定的路径。并且 Link 只能有一个直接子节点。
####手动跳转
1 | import Router from 'next/router' |
###动态路由
- query 参数
接收的时候需要用到next/Router
1 | import {withRouter} from 'next/router |
- 路由映射
使用 as 属性定义显示的方式
1 | <LInk href="/a?id=1" as ="/a/1" > |
这样/a?id=1
会被显示成/a/1
; 但这有个问题,当刷新的时候就会出现 404,因为这种映射是在前端的,服务端并没有/a/1
的资源。
因此服务端需要对/a/1
的请求做下处理,转换成原来的/a?id=1
;使用 koa 的 router
1 | const router = new Router() |
getInitialProps
只有放在 pages 文件下的 getInitialProps 才会被调用;具体内容查看官网介绍;
- 在页面中获取数据
- 在 App 文件中获取数据
需要注意的是:如果在 getinitialProps 中异步获取数据,当点击 Link 进行跳转时,等到异步数据获取到才会跳转过去,这就会有延迟的问题。点击跳转可能半天才过去。
自定义 App
nextjs
的app
(也就是_app.js
)相当于母版、基类的作用。我的理解就是一个高阶组件。pages 文件夹下的每个页面都会经过 App 进行“包装”。
app 的作用:
- 固定 Laout
- 保持一些公共的状态
- 给页面传入一些自定义数据
- 自定义错误处理
1 | import App, { Container } from "next/app"; |
###自定义 document
document 是只有在服务端渲染的时候才会被调用。
用来修改服务端渲染的文档内容。
一般用来配合第三方 css-in-js 方案使用。
创建和_app.js 一样,在 pages 文件夹下创建下划线开头的文件_document.js
1 | import Document, { Html, Head, Main, NextScript } from "next/document"; |
style-css
是组件级的,每个组件中的样式不会影响其他组件,组件和组件之间是隔离的,即使定义的是 global 的,也是组件级的。每个组件的元素上会添加一个类似jsx-12342131231
的样式,这就是组件隔离的原因所在。并且当组件别卸载时,样式也会被删除,所以不会影响其他组件的样式。
1 | <style jsx> |
上面的样式在元素上就会是jsx-32342342 fontSize
;
但如果同一个页面中的两个子组件都定义了相同的全局样式,还是会影响的(废话)。
###LazyLoading
- 异步加载模块
1 | const moment = await import("moment"); |
- 异步加载组件
1 | import dynamic from "next/dynamic"; |
###next.config.js 的配置
这个文件就是让我们来重置 nextjs 的配置。
1 | const config = { |
###redux-devtools-extension 的使用
安装后,把 applyMiddleware 传给它的方法即可。