После прочтения маршрутизации next.js

React.js

предисловие

В этой статье будет представлен контент next.js, связанный с маршрутизацией.Как новичок, автор знает, что в статье не так много подробностей, и он надеется только помочь друзьям начального уровня, таким как автор. Эта статья основана на предыдущейСреду next.js+koa2+antd легко построить

Структура каталогов next.js

Прежде чем представить маршрутизацию, я хотел бы кратко рассказать о структуре каталогов, некоторые из которых очень полезны для объяснения маршрутизации.

├── .next
│   ├── build-manifest.json
│   ├── react-loadable-manifest.json
│   ├── server
│   └── static
├── components
│   ├── head.js
│   └── nav.js
├── pages
│   ├── _app.js
│   └── index.js
├── static
│   └── favicon.ico
├── server.js
├── .babelrc
├── .gitignore
├── next.config.js
├── package.json
├── README.md
└── yarn.lock

ЭтоСреду next.js+koa2+antd легко построитьКаталог файлов next+koa2+antd, созданный в статье, в которойREADME.md,package.json,yarn.lock,.gitignoreНе говоря уж о.

pagesа такжеcomponents pagesЭто очень важный каталог в next.js, в котором каждый файл js представляет собой страницу, но есть два исключения, одно используется в предыдущей статье._app.js,один_document.js. Давайте создадим еще один a.js и test/b.js под страницами и посмотрим на эффект

// a.js
export default () => <div>this is a page</div>

// test/b.js
export default () => <div>this is b page</div>

Мы можем обнаружить, что next.js автоматически генерирует соответствующий маршрут для файла js на страницах в соответствии с его путем и именем файла.

Но когда мы снова пишем страницы, невозможно разместить все под страницами, мы можем поместить конкретный контент как компоненты вcomponentsкаталог, затем вpagesПредставлен в соответствующем файле js. Если это небольшой партнер, который создает проект с помощью инструмента для строительных лесов, это можно увидеть интуитивно.componentsв каталогеhead.jsnav.jspages/indx.js

.next:.next

staic.babelrcnext.config.jsserver.js

Link

import Link from 'next/link' //引入Link组件
import { Button } from 'antd' //引入antd中的Button组件

export default () => {
  return (
    <Link href="/a">
      <Button>跳转到A</Button>
    </Link>
  )
}

href/a

React.Children.only

<Link href="/a">
  <Button>跳转到A</Button>
  <Button>也跳转到A</Button>//报错
</Link>

<div>

<div>
  <Button>跳转到A</Button>
  <Button>也跳转到A</Button>
</div>

Link

import Link from 'next/link'
import Router from 'next/router' // 新引入进来的
import { Button } from 'antd'

export default () => {
  const goToB = () => {
    Router.push('/test/b')
  }
  return (
    <>
      <Link href="/a">
          <Button>跳转到A</Button>
      </Link>
      <Button onClick={goToB} >跳转到B</Button> // 新增的一个Button组件
    </>
  )
}

goToBgoToBgoToB/test/b/test/b.js

/test/:idquery/test?id=xx

<Link href="/a?id=1">
  <Button>跳转到A</Button>
</Link>

Router.push()

const goToB = () => {
  Router.push({
    pathname: '/test/b',
    query: {
      id: 2
    }
  })
}

import { withRouter } from 'next/router' //新引入的
const A =  ({ router }) => <div>this is a page,参数是{router.query.id}</div>

export default withRouter(A)

withRouter

/test?id=xxx/test/xxx

<Link href="/a?id=1" as="/a/1">
    <Button>跳转到A</Button>
</Link>

Router.push({
  pathname: '/test/b',
  query: {
    id: 2
  }
}, '/test/b/2')

然后在浏览器中创建一个路由

localhost:3000/apages/a.js/a/a/1pages/a/1.js

npm install koa-router --saveyarn add koa-router

/*
* @Author: yishuai
* @Date:   2019-04-21 09:57:53
* @Last Modified by:   yishuai
* @Last Modified time: 2019-04-21 12:22:22
*/
const Koa = require('koa')
const Router = require('koa-router') // 引入路由
const next = require('next')

const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()

app.prepare().then(() => {
  const server = new Koa()
  const router = new Router() // 定义路由

  // 设置路由,与next.js的路由进行映射
  router.get('/a:id', async (ctx) => {
  // handle传入的第三个参数跟我们next.js中用Router.push({})传入的数组一样
    await handle(ctx.req, ctx.res, {
      pathname: '/a',
      query: {
        id
      }
    })
    ctx.respond = false
  })

// 使用路由
  server.use(router.routes())
  server.use(async (ctx, next) => {
    await handle(ctx.req, ctx.res)
    ctx.respond = false
  })

  server.listen(3000, () => {
    console.log('server is running at http://localhost:3000')
  })
})

localhost:3000/a/1

componentDidMount(){xxxxxx}xxxxxxxxxxxxxxx

添加了

// 所有的路由钩子名称,写在了一个数组中
const events = [
  'routeChangeStart',
  'routeChangeComplete',
  'routeChnageError',
  'beforeHistoryChange',
  'hashChangeStart',
  'hashChangeComplete'
]

// 通过一个高阶函数在钩子触发后执行自定义的逻辑,这里直接输出了钩子名称和钩子函数的参数
function makeEvent(type) {
  return (...args) => {
    console.log(type, ...args)
  }
}

//通过forEach遍历 绑定钩子事件
events.forEach(event => {
  Router.events.on(event, makeEvent(event))
})

routeChangeStart

Router.events.on('routeChangeStart', function(...args){
    console.log('routeChangeStart',...args)
})

Router.events.on()

跳转到A

routeChangeStart...argslocalhost:3000beforeHistoryChangerouteChangeComplete

import { withRouter } from 'next/router'
import Link from 'next/link' // 新引入的

// 外层加了个a标签和Link标签,Link标签跳转到hash路由#hello
const A =  ({ router }) => <Link href="#hello"><a><div>this is a page,参数是{router.query.id}</div></a></Link>

export default withRouter(A)