Advanced-Frontend / Daily-Interview-Question

我是依扬(木易杨),公众号「高级前端进阶」作者,每天搞定一道前端大厂面试题,祝大家天天进步,一年后会看到不一样的自己。
https://muyiy.cn/question/
27.39k stars 3.29k forks source link

第 85 题:react-router 里的 <Link> 标签和 <a> 标签有什么区别 #135

Open yygmind opened 5 years ago

yygmind commented 5 years ago

如何禁掉 <a> 标签默认事件,禁掉之后如何实现跳转

wingmeng commented 5 years ago

从最终渲染的 DOM 来看,这两者都是链接,都是 <a> 标签,区别是: <Link> 是 react-router 里实现路由跳转的链接,一般配合 <Route> 使用,react-router 接管了其默认的链接跳转行为,区别于传统的页面跳转,<Link> 的“跳转”行为只会触发相匹配的 <Route> 对应的页面内容更新,而不会刷新整个页面。 而 <a> 标签就是普通的超链接了,用于从当前页面跳转到 href 指向的另一个页面(非锚点情况)。

lhyt commented 5 years ago

先看Link点击事件handleClick部分源码

      if (_this.props.onClick) _this.props.onClick(event);

      if (!event.defaultPrevented && // onClick prevented default
      event.button === 0 && // ignore everything but left clicks
      !_this.props.target && // let browser handle "target=_blank" etc.
      !isModifiedEvent(event) // ignore clicks with modifier keys
      ) {
          event.preventDefault();

          var history = _this.context.router.history;
          var _this$props = _this.props,
              replace = _this$props.replace,
              to = _this$props.to;

          if (replace) {
            history.replace(to);
          } else {
            history.push(to);
          }
        }

Link做了3件事情:

  1. 有onclick那就执行onclick
  2. click的时候阻止a标签默认事件(这样子点击<a href="/abc">123</a>就不会跳转和刷新页面)
  3. 再取得跳转href(即是to),用history(前端路由两种方式之一,history & hash)跳转,此时只是链接变了,并没有刷新页面
mengsixing commented 5 years ago
sohoorc commented 5 years ago

Link 的本质也是a 标签。只不过在Link 中禁用了 a 标签的默认事件,改用了history对象提供的方法进行跳转。

meiseayoung commented 5 years ago

<a href="javascript: void 0" @click="$router.push(route)">

edsyang commented 4 years ago

link会根据HASH的形态不同自动调整

dbfterrific commented 4 years ago
  • Router

history 跟 hash 模式混为一谈了吧...

Gao-S-Hua commented 4 years ago

之前遇到过一个bug, 在一个SPA里点击一个链接按钮后,redux里的数据都丢了。后来才发现,不知道谁写了一个a,没有用Link。相当于重新打开了一个SPA。

luckyxutao commented 4 years ago

之前遇到过一个bug, 在一个SPA里点击一个链接按钮后,redux里的数据都丢了。后来才发现,不知道谁写了一个a,没有用Link。相当于重新打开了一个SPA。

你说的对,这才是最大的区别

vkboo commented 3 years ago
Yangfan2016 commented 2 years ago
<a onClick={ev=>{
  ev.stopPropagation();
  history.pushState(null,null,"/home");
}}>click me</a>