предисловие
В этой статье будет представлен контент 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.js
nav.js
pages/indx.js
.next:.next
staic
.babelrc
next.config.js
server.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组件
</>
)
}
goToB
goToB
goToB
/test/b
/test/b.js
/test/:id
query
/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/a
pages/a.js
/a
/a/1
pages/a/1.js
npm install koa-router --save
yarn 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}
xxxxxxxx
xxxxxxx
添加了
// 所有的路由钩子名称,写在了一个数组中
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
...args
localhost:3000
beforeHistoryChange
routeChangeComplete
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)