一、导航与链接
在 Next.js 中有4种方式实现导航:
1、使用 <Link> 组件
<Link href="/dashboard">跳转路由</Link>
2、使用 useRouter Hook (客户端组件,搭配'use client')
'use client'
import { useRouter } from 'next/navigation';
let router = useRouter()
// 使用
router.push('/dashboard')
3、使用 Redirect 函数 (服务端组件)
import { redirect } from 'next/navigation';
// 使用
redirect('/dashboard')
4、使用浏览器的原生History API
// 入栈
window.history.pushState(null,'','/dashboard')
// 替换
window.history.repalceState(null,'','/dashboard')
这里记录几个来源:
import { useRouter, usePathname, redirect } from 'next/navigation';
inport Link from 'next/link';
二、路由种类及详解
1、动态路由
[folderName]
创建文件夹和文件名为 dashboard/[slug]/page.js ,这个参数是通过 props.params 传入的
页面上的显示:
[...folderName]
表示会捕获所有后面的路由片段,他们会共用同一个组件,很好地提高组件的复用,如果既有[folderName]和[...folderName],加一个路由片段时,会优先匹配[folderName],
实验一下这种情况:
[[...folderName]]
与[...folderName]不同的是,不带参数的路由也会被匹配到,及可以匹配/dashboard,前提是没有映射的文件路径/dashboard/page.js,如果存在此路径,使用[[...folderName]]就会报错。
[...folderName] 和 [[...folderName]]、[...folderName] 和 dashboard/page.js 不能在同一层级中同时存在,否则会报错。
其实官方文档中把 [...folderName] 称为 Catch-all Segements,把 [[...folderName]] 称为 Optional Catch-all Segements,猜测两者只是同一种匹配的不同写法,所以是不能同时存在的。
使用组合为dashboard/page.js、[folderName]、[...folderName],要不就直接用[[...folderName]],只有 [folderName] 和 [[...folderName]] 一块用时不会报错,且会优先匹配 [folderName] 页面。
2、路由组
概念:将文件夹标记为路由组,阻止文件名被映射到路径中(及文件中标识为路由组的文件名不会出现在路径中)
作用:
1)按站点、意图、团队等分组(可以理解为一种项目结构上的规范)
2)同一层级可以创建多个布局或根布局
记号:(dashboard)
注意:
1)如果存在 (marketing)/about/page.js 和 (shop)/about/page.js ,都会被解析为 /about,故页面会报错
2)如果 app 下的 layout.js 删了,即项目的入口没有了,page.js 需要移到任一个路由组中,此时改路由组作为根路径 "/" 存在
这里实验一下 page 被移到 (marketing) 下:
3)跨根布局会被重新加载
3、平行路由
平行路由也不会对 url 路径产生影响,用法有点类似于 Vue 中的插槽,用于不同页面在 layout 上的布局(Vue是用组件实现的,这里 Next.js 引用的则是页面page)
其实可以理解 app/page.js => app/@children/page.js
平行路由其实就是我们直接在 page 引入组件布局的一种变体,原因是 Next.js 抽离了 layout,所以配套地增加平行路由,也是为了让开发者遵循在 layout 中进行布局的规范。还有一个好处就是因为都是 page,可以拥有自己的一套 loading、error、not-found等处理方法。
用途:
1)条件渲染
2)独立路由处理(也就是loading、error、not-found等)
3)子导航
子页面和子页面之间互不影响,跳到 analytics-view 再跳到 team-view 并不会影响 analytics-view 的输出,但其实 @team 也去找 analytics-view 匹配了,只不过没找到而已。
当地址发生变化,所有页面都会去找路由,没找到不会变化,但刷新页面时会报错,应为匹配不上了!!!
报错的情况:
当所有页面都加上 analytics-view 时再刷新就不会报错了:
为了解决这个问题,Next.js 引进了 default.js 来代替所有因为路由不匹配产生的404问题,匹配不到就显示 default.js 里的内容,就不用一套一套地配置子导航了。
4、拦截路由
拦截路由的 Demo 演示:https://nextjs-app-route-interception.vercel.app/
拦截路由的意义,简单的来说,就是希望用户继续停留在重要的页面上。比如上述例子中的图片流页面,开发者肯定是希望用户能够持续在图片流页面浏览,如果点击一张图片就跳转出去,会打断用户的浏览体验,如果点击只展示一个 Modal,分享操作又会变得麻烦一点。拦截路由正好可以实现这样一种平衡。又比如任务列表页面,点击其中一项任务,弹出 Modal 让你能够编辑此任务,同时又可以方便的分享任务内容。
文件架构:
拦截路由感觉上就是页面上的交互都是用“假的”路由下的页面的内容,即 app/(.)photo/[id]/page.js ,只有复制地址到地址栏打开才是真正的页面,即 app/photo/[id]/page.js
拦截路由拦截了谁具体的匹配规则如下: