Pages页面用法
1.1 概念介绍
在 Next.js 中,一个 page(页面) 就是一个从 .js、jsx、.ts 或 .tsx 文件导出(export)的 React 组件 ,这些文件存放在 pages 目录下。每个 page(页面)都使用其文件名作为路由(route)。
1.2 创建page页面
如果你创建了一个命名为 pages/about.jsx 的文件并导出(export)一个如下所示的 React 组件,则可以通过 /about 路径进行访问。 function About() {
return
}
export default About
如果你创建了一个命名为 pages/home/index.jsx 的文件并导出(export)一个如下所示的 React 组件,则可以通过 /home 路径进行访问。function Home() {
return
}
export default Home
注意:项目启动时默认加载的首页页面冲突问题:
当 src/app/page.jsx 默认首页文件存在的时候,此页面将作为 http://localhost:3000 的默认启动页面。如果此时在 pages 目录下又新建了 index.jsx 页面,就会和 src/app/page.jsx 中的页面产生冲突,导致首页无法正常加载。因此,两者只存在一个即可,另外一个相关文件要删除。
1.3 路由分类
Index routes:索引路由
路由将自动跳转到 pages 目录下名为 index 的路由文件。
比如: pages/index.jsx → /
pages/blog/index.jsx → /blog
Nested routes:嵌套目录路由
路由器支持嵌套文件。如果创建嵌套文件夹结构,文件仍将以相同的方式自动路由。
比如: pages/blog/first-post.js → /blog/first-post
pages/dashboard/settings/username.js → /dashboard/settings/username
Dynamic route segments:动态参数路由
使用 [] 括号语法,可以进行动态路由参数的匹配。
比如: pages/blog/[slug].js → /blog/:slug (/blog/hello-world)
pages/[username]/settings.js → /:username/settings (/foo/settings)
pages/post/[...all].js → /post/* (/post/2020/id/title)
1.4 声明式路由跳转页面
介绍
Next.js路由器允许您在页面之间进行客户端路由转换,类似于单页面应用程序。
修改 src/app/page.jsx 默认页面,通过字符串方式配置路由页面的跳转链接: import Link from "next/link";
function App() {
return (
主页
个人中心
);
}
export default App;
上面的 ul 使用了多个 href 链接。每一个(href)都映射到一个已知页面组件: /home → pages/home/index.jsx
/profile → pages/profile/index.jsx
通过url对象方式配置路由跳转:
主页
重定向路由实现页面跳转:
Link 组件默认将 url 推入路由栈中,生成一个路由跳转历史记录。你可以使用replace属性来重定向路由,防止生成路由历史记录。
主页
Link组件下的children只能是单独的一个,而不能是多个子节点:
组件API汇总:
href - 导航的目标路径或 URL,这是唯一一个必须设置的属性;as - 可选的路径装饰符,用于改变显示在浏览器地址栏中的URL格式。如果你在服务器端设置了自定义路由as将会起作用,否则页面切换会出现404情况;
as 路由映射是指:比如有一个路由是 /post?id=2&articleId=199,这样的路由看起来是不友好的。我们想要在浏览器地址栏中看到 /post/2/199,这样的路径。从前种方法到后种方法之间的转换就叫做路由映射。使用 next 中的 组件提供的as属性,就可以实现路由格式的转换。as 是浏览器地址栏显示的path,并不是真正的path;而href才是真正的跳转路径。as只是改变了以下路由的外观,本质还是href。
1.5 编程式路由跳转页面
介绍
除了使用声明式路由,还可以用 next/router 或者 next/navigation 的编程式路由API实现客户端路由切换。
src/app/page.jsx 首页页面如果要配置编程式API进行路由跳转,需要使用:next/navigation 搭配 "use client" 才可以正确使用useRouter,因为 app/page.jsx 页面默认属于服务端组件了,而不是客户端组件。 "use client"; // 必须要添加
import Link from "next/link";
import { useRouter } from "next/navigation";
function App() {
const router = useRouter();
return (
);
}
export default App;
如果 src/app/page.jsx 使用 next/router 则会报如下错误: You have a Server Component that imports next/router. Use next/navigation instead.
Maybe one of these should be marked as a client entry "use client":
./src\app\page.jsx
如果是非 src/app/page.jsx 页面的其它路由组件,配置编程式导航,则使用 next/router,比如:src/pages/home/index.jsx 页面: import { useRouter } from "next/router";
export default function Home() {
const router = useRouter();
return (
首页
);
}
const router = useRouter() 返回的router对象API汇总:
router.push(url, as, options):进入某个路由;第二个参数as,是为了装饰 URL ,如果你在服务器端设置了自定义路由将会起作用。router.replace(url, as, options):重定向路由;router.back():返回上一个路由;router.reload():重载当前路由;router.prefetch(url, as):预读取某个路由的组件内容;仅在生产环境下有效;router.beforePopState(cb):在路由器处理事件之前拦截
1.6 路由页面的预读取prefetch
介绍
Next.js 一个非常实用的功能就是你在浏览当前页面的时候,Next.js 会自动 prefetch 页面上所有的站内链接页面。这样一来,当你真正点击某个链接时,就可以迅速加载该页面,快得简直就像是在读取本地文件。 可能这就是为什么同样是 client-side navigation(客户端导航),Next.js 要比常规的 React SPA 的页面跳转快这么多吧!
这个功能在 中是默认开启的。除非像下面这样把 的 prefetch 置为 false,Next.js 就不会在当前页面,再去 prefetch 该路由:
prefetch 属性会在后台预读取目标路由页面,默认值为 true。它具有以下特性:
处于视口(viewport)中(初始或滚动后)的任何 都将被预加载。通过设置 prefetch={false} 可以禁止页面预取。当 prefetch 被设置为 false 时,鼠标悬停在 上时仍然会触发预取。使用 静态生成 的页面(pages)将预加载存有数据的 JSON 文件,以实现更快的页面切换。预取功能只在生产环境中开启。 router.prefetch(url, as, options) 编程式API进行页面预读取: // 假设您有一个登录页面,登录后,您将用户重定向到仪表板。
// 对于这种情况,我们可以预取仪表板以进行更快的转换,如以下示例所示:
import { useCallback, useEffect } from 'react'
import { useRouter } from 'next/router'
export default function Login() {
const router = useRouter()
const handleSubmit = useCallback((e) => {
e.preventDefault()
fetch('/api/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({}),
}).then((res) => {
if (res.ok) router.push('/dashboard')
})
}, [])
useEffect(() => {
// 预读取 /dashboard 页面
router.prefetch('/dashboard')
}, [router])
return (
)
}
prefetch 的内容是如何存储的?
通过 的方式,浏览器会请求相应的 .js 和 .css 文件,但不会执行它们,而是作为缓存把它们储存在浏览器中。等到用户真正跳转到该 route,需要加载这些文件时,就可以直接从本地加载,不需要请求服务器了,其实也是一种前端提高性能的常见方法。
相关阅读
发表评论