• Hello World

安装:npm install next react react-dom -S

然后根目录新建pages文件夹,写个index.js

import React, { Component } from 'react'

export default class index extends Component {
  render() {
    return (
      <div>
        Hello Next
      </div>
    )
  }
}

package.json加入命令:

"scripts": {
    "dev": "next"
},

然后npm run dev即可,而且还支持热更新。

  • 加入css

按照官方写的做就可以了。有的说安装会出问题,我倒是很正常。

  • 加入less,sass等

也按照官方写的做就可以了,要说的是如何又加css又加less。在next.config.js中按下面这样写就可以了

const withCSS = require('@zeit/next-css')
const withLess = require('@zeit/next-less')
module.exports = {
  webpack(config, ...args) {
    config = withCSS().webpack(config, ...args)
    config = withLess().webpack(config, ...args)
    return config
  } 
}
  • 定制Head

方式一:

import Head from 'next/head'
export default class index extends Component {
  render() {
    return (
      <div className='hello'>
        <Head>
          <title>Learn Next</title>
        </Head>
        Hello Next!!
      </div>
    )
  }
}

方式二:可以写成一个组件,到处用。

pages/components/Layout.js

import React from 'react'
import Head from 'next/head'

export default ({children}) => (
  <div>
    <Head>
      <title>Learn Next</title>
    </Head>
    {children}
    <footer>copyright@2020</footer>
  </div>
)

app.js

export default class index extends Component {
  render() {
    return (
      <Layout>
        <div className='hello'>
          Hello Next!!
        </div>
      </Layout>
    )
  }
}
  • 生命周期

有一个getInitialProps的钩子函数,在初始化props时被调用,只在服务端运行,没有跨域的限制。这个不能用于子组件,只能用于页面组件

App.js

export default class index extends Component {
  static async getInitialProps() {
    const res = await axios.get('your_api_url')
    return {
      cityInfo: res.data.cityInfo
    }
  }

  render() {
    return (
      <Layout>
        <div className='hello'>
          Hello Next!!
          <p>{this.props.cityInfo.city}</p>
        </div>
      </Layout>
    )
  }
}
  • 路由

基本使用:

import Link from 'next/link'
export default class index extends Component {
  render() {
    return (
      <Layout>
        <div className='hello'>
          Hello Next!! <br/>
          <Link href='/'>Home</Link> | 
          <Link href='/list'>List</Link> |
          <Link as='d' href='/detail'>Detail</Link>
        </div>
      </Layout>
    )
  }
}

as叫做route mask,就是给路由起个别名。

传参:

list/index.js

import React, { Component } from 'react'
import Router from 'next/router'

export default class index extends Component {
  state = {list:['kobe', 'tracy', 'tim', 'oneal']}
  render() {
    return (
      <div>
        <ul>
          {this.state.list.map(l => {
            return <li onClick={() => Router.push({
              pathname: '/detail',
              query: {arg: l}
            })} key={l}><a>{l}</a></li>
          })}
        </ul>
      </div>
    )
  }
}

detail/index.js

import React, { Component } from 'react'
import { withRouter } from 'next/router'

class index extends Component {
  render() {
    const { router } = this.props
    return (
      <div>
        <h1>Detail</h1>
        <p>{router.pathname}</p>
      </div>
    )
  }
}

export default withRouter(index)
  • 路由的预加载

首先,这玩意只有production,也就是只有发布后才能有用,开发阶段是没有的。有两种做法:

<Link href='/' prefetch>Home</Link>

还有就是用withRouter

import withRouter from 'next/router';

export default withRouter(({children, router}) => (
	<div>
        {router.prefetch('/')}
    </div>
))
  • 路由守卫

即控制路由权限。常见方式是利用路由的事件,路由有跳转开始、跳转完成、跳转失败、浏览器历史改变这几个事件,所以,应该在跳转开始前就拦截掉。

import Router from 'next/router'

Router.events.on('routeChangeStart', (url) => {
  if (url === '/l' || url === '/list') {
    location.href = './detail' 
  }
})

这样就能将本来要跳转到list页面的路由redirect都detail页面。

  • 错误页面

pages下写个_errors.js即可

  • Redux

官网的安装一下即可,我用yarn安装的。看了下他的例子,我说怎么多了一些没见过的东西,原来有了新api,这个到时候再研究。

  • 部署
"scripts": {
    "dev": "next",
    "build": "next build",
    "start": "next start -p 80",
    "dev_e": "cross-env NODE_ENV=dev node server.js",
    "start_e": "cross-env NODE_ENV=production node server.js"
}

package.json加上上面的内容,就可以用npm run build来打包了,然后npm run start就可以部署到80端口了。如果想要和express结合,就随便在哪,比如根目录新建一个server.js

const express = require('express')
const next = require('next')
const dev = process.env.NODE_ENV !== 'production'
const app = next({dev})
const handle = app.getRequestHandler()
app.prepare().then(() => {
  const server = express()
  server.get('*', (req, res) => {
    return handle(req, res)
  })
  server.listen(3000, (err) => {
    console.log('Ready on http://localhost:3000')
  })
})

express先拦截了所有链接,然后交给next去处理。npm run start_e就可以启动了。