Blitz 尚在 beat 阶段! 🎉 预计会在今年的 Q3 季度发布 1.0
Back to Documentation Menu

<Link>

Topics

Jump to a Topic

<Link>用于页面间的导航

一个链接HomeAbout页的例子:

import {Link, Routes} from "blitz"

function Home() {
  return (
    <ul>
      <li>
        <Link href={Routes.Home()}> // Option 1: use Route manifest
        <Link href="/"> // Option 2: use string or location object
          <a>Home</a>
        </Link>
      </li>
      <li>
        <Link href={Routes.About()}> // Option 1: use Route manifest
        <Link href="/about"> // Option 2: use string or location object
          <a>About Us</a>
        </Link>
      </li>
    </ul>
  )
}

export default Home

blitz导入的Routes对象是根据你的应用程序中的页面自动生成的。如果你的 页面组件名称叫 About, 那么你可以使用Routes.About链接到该组件。可以参 考Route Manifest 文档了解更多信息。

Link组件可以接受以下属性:

  • href - pages目录中的路径,这是唯一需要的属性
  • as - 将在浏览器 URL 栏里显示的路径,用于动态路由
  • passHref - 强制 Linkhref 属性传递给子元素。默认值为 false
  • prefetch - 在后台预取页面。默认值为true。任何在视口中(初始或滚动后) 的<Link />都将被预加载。通过设置 prefetch={false}可以禁用预取功能。 当prefetch被设置为false时,鼠标悬停在 <Link />上时仍会触发预取。使 用静态生成的页面将预加载带有数据的JSON 文件 ,以实现更快的页面转换。预取功能只在生产环境中启用。
  • replace - 替换当前的history状态 ,而不是在 history堆栈中添加新的 url。默认值为false
  • scroll - 滚动至导航后的页 面顶部。默认值为true
  • shallow - 更新当前页面的路径,不需要重新运 行getStaticPropsgetServerSideProps。默认值为false

对于外部的 URL 以及任何不需要使用/pages路由导航的链接,不需要用Link来 处理。这种情况下,可以使用 a 标签代替。

动态路由

Link组件链接至动态路由的原理和其他链接相似。一个链接 到pages/post/[pid].js页的 link 写法如下:

<Link href={Routes.Post({ pid: "abc" })}>
  <a>First Post</a>
</Link>

下面是一个如何创建 link 列表的例子:

const pids = ["id1", "id2", "id3"]
{
  pids.map((pid) => (
    <Link href={Routes.Post({pid})}> // using Routes Manifest
    <Link href={`/posts/${pid}`}> // using location
      <a>Post {pid}</a>
    </Link>
  ))
}

如果子项是一个包含<a>标签的自定义组件

如果Link的子组件是一个包含 <a> 标签的自定义组件,那么你必须在Link中 添加passHref属性。如果你在使用像 styled-components这样的库时,这个操作是 必须的。如果不这样做,<a>标签将会没有 href 属性,这可能会损坏网站的 SEO。

import { Link } from "blitz"
import styled from "styled-components"

// This creates a custom component that wraps an <a> tag
const RedLink = styled.a`
  color: red;
`

function NavLink({ href, name }) {
  // Must add passHref to Link
  return (
    <Link href={href} passHref>
      <RedLink>{name}</RedLink>
    </Link>
  )
}

export default NavLink

注意: 如果你在使用emotion的 JSX pragma 功能 (@jsx jsx),你必须使用passHref属性,即使你直接使用的是<a>标签。

如果子项是一个函数式组件

如果Link的子组件是一个函数式组件,除了需要使用passHref属性之外,你还必 须把组件包 在React.forwardRef 中。

import { Link, Routes } from "blitz"

// `onClick`, `href`, and `ref` need to be passed to the DOM element
// for proper handling
const MyButton = React.forwardRef(({ onClick, href }, ref) => {
  return (
    <a href={href} onClick={onClick} ref={ref}>
      Click Me
    </a>
  )
})

function Home() {
  return (
    <Link href={Routes.About()} passHref>
      <MyButton />
    </Link>
  )
}

export default Home

携带 URL 对象

Link组件也可以接收一个 URL 对象,它会自动格式化该 URL 对象,以便创建 URL 字符串。写法如下:

import { Link } from "blitz"

function Home() {
  return (
    <div>
      <Link href={{ pathname: "/about", query: { name: "test" } }}>
        <a>About us</a>
      </Link>
    </div>
  )
}

export default Home

上述示例将会链接到/about?name=test。你可以使 用Node.js URL 模块文档中 定义的每一个属性。

替换 URL 而非推送

Link组件的默认行为是将新的 URLpushhistory堆栈中。你可以使 用replace属性来阻止向 history 堆栈中增加新内容,如下示例:

<Link href={Routes.About()} replace>
  <a>About us</a>
</Link>

使用支持onClick 的组件

Link支持任何支持onClick事件的组件,如果你不提供<a> 标签,考虑如下示 例:

<Link href={Routes.About()}>
  <img src="/static/image.png" alt="image" />
</Link>

Link的子项是 <img> 标签而非<a> 标签。Link会将onClick属性传递 给<img>,但是不会传递href属性。

禁止滚动到页面顶部

Link的默认行为会滚动到页面,当有 hash 定义时,页面将会像普通的<a>标签 一样滚动到对于的 id 上。为了阻止滚动到页面顶部/hash 上,可以给 Link 添 加scroll={false}

<Link href="/?counter=10" scroll={false}>
  <a>Disables scrolling to the top</a>
</Link>

Idea for improving this page? Edit it on GitHub.