「读懂源码系列1」还在恐惊读源码?看完这篇就不怕了

一个小需求

事变的原由,是昨天有一个新的需求被提出。

需求是要完成,让我们本身定制的弹出层,具有按下 ESC 也能退出的功用。我把使命交给了同组的小伙伴S去完成。(这个项目用到了vue手艺栈,以及饿了么的UI框架。)

我开完会返来,发明他还在处置惩罚谁人功用,但彷佛碰到了什么瓶颈。因而,我就问他,卡在了什么地方。

小伙伴S说,他百度了不少材料,还查了官方文档,而且尝试个中的要领,但就是没法触发按下 ESC 的回调要领,异常忧郁。我看了他的代码,他的写法是如许的:

<div class="custom-modal" @keydown.27="handlePressEscape">
    ...
</div>
...
handlePressEscape () {
    console.log('press escape!');
},
...

他的主意不错,由于是自定义的弹出层,所以就想着把 keydown 事宜,绑定在最外层的 div 上,让全部弹出层都能监听到。

他给我看了他查的材料,险些都是在 input 上绑定 keydown 事宜的例子,而 vue 的官方文档里也是相似的例子,实践后却陷入了瓶颈。然则他疏忽了一个问题,keydown 事宜,并不是绑在恣意一个标签上,都邑起作用

一种思绪

我没有直接把答案通知他,而是给他供应了一个思绪:在我们常常运用的 element-ui 的 el-dialog 组件里,有个属性叫做 close-on-press-escape,它的诠释如下图:

《「读懂源码系列1」还在恐惊读源码?看完这篇就不怕了》

从文档的诠释,能够看出 el-dialog 在默许情况下,已完成了我们须要处理的需求。所以,我让他看看 el-dialog 的源码,是怎样完成的。

他一听要看源码,就露出了恐惊之情。

《「读懂源码系列1」还在恐惊读源码?看完这篇就不怕了》

源码是一切框架和API的基础,由于比较庞杂深奥,所以让人很抗拒。我本身也经历过这个阶段,所以异常邃晓他的心境,勉励他一同做一次尝试。

查找源码

起首,我们在 node_modules 里,找到了 element-ui的文件夹,它大抵长这个模样:

《「读懂源码系列1」还在恐惊读源码?看完这篇就不怕了》

接着,我们找到了 packages 里的 dialog 文件夹,再从 index 进口,找到了组件 component.vue。但是,点进去找了半天,也只找到个 closeOnPressEscape 属性的定义,却没有完成的要领。

...
closeOnPressEscape: {
    type: Boolean,
    default: true
},
...

这么奇异么?只定义一个属性,就可以完成一个事宜的交互了?

觉得不太可能啊?!? 为了揭开迷雾,继承找。。。

细致阅读了 component.vue 文件,发明在 script 里,引入下面 3 个文件:

import Popup from 'element-ui/src/utils/popup';
import Migrating from 'element-ui/src/mixins/migrating';
import emitter from 'element-ui/src/mixins/emitter';
...

在第一个引入的 Popup 中,居然也发明了 closeOnPressEscape,觉得好像找对方向了。

但使人懊丧的是,Popup 中一样只要 closeOnPressEscape 的属性定义,却没有完成。不过,它却引入了另一个辅佐文件 PopupManager,再点进去找。

哇!终究找到了!它的完成,是如许的:

// handle `esc` key when the popup is shown
window.addEventListener('keydown', function(event) {
    if (event.keyCode === 27) {
        const topPopup = getTopPopup();

        if (topPopup && topPopup.closeOnPressEscape) {
            topPopup.handleClose
                ? topPopup.handleClose()
                : (topPopup.handleAction
                    ? topPopup.handleAction('cancel')
                    : topPopup.close());
        }
    }
});

本来,是在 window 上增加了事宜监听 keydown,当监测到是 ESC 的 keyCode 时,则实行相干操纵。

模拟源码

ok,如今已晓得了道理,那就根据我们的现实需求,模拟革新一下:

...
props: {
    ...
    closeOnPressEscape: {
        type: Boolean,
        default: true
    }
},
...
mounted () {
    window.addEventListener('keydown', this.handlePressEscape);
},

destroyed () {
    window.removeEventListener('keydown', this.handlePressEscape);
},

methods: {
    ...
    handlePressEscape (event) {
        if (this.closeOnPressEscape && event.keyCode === 27) {
            this.handleClose();
        }
    }
}

在上述完成中,有2个须要注重的点:

  • 代码方面,在 mounted 中,给 window 增加事宜监听以后,要记得在 destroyed 时,去除监听。
  • 营业方面,这是一个我们定制的通用的弹出层组件,所以在 props 中定义了一个 closeOnPressEscape 属性,以方便在某些营业场景下,不须要按 ESC 就退出这个功用的时刻,直接设置它为 false 即可。

到此为止,全部事宜画上了美满的句号。

源码真有那末恐怖吗?

源码一词,乍一听就是神奇、嵬峨上、吊炸天的代名词,让许多的前端同砚心惊胆战。追念当初,我也曾一度对它有一股深深的恐惊。

源码真的这么恐怖吗?

从以上的事例中能够看出,实在并没有。例子中的element-ui源码并不庞杂,我和小伙伴S一同看源码时,他也也许都能看得邃晓。末了由于弄懂了背地的道理,举行简朴运用,比较轻松地就处理了问题。

关于源码的恐惊,让我们逐渐头脑固化,本身通知本身不要去碰源码,时候长了就遗忘了另有如许一条路可走。

口试中的运用

关于对源代码的考核,我也会常常运用在口试中。在口试中,假如候选人给我的觉得不错,我的习用手法是问下面这个问题:

适才你说到,用过一段时候 xxx 框架,xx API属性也用过,也很清晰它到达的结果。

那末如今,假如须要你完成一个相似的结果,抛开 xxx 框架以及 xx API属性,

你会怎样去完成,有无其他思绪?

这个问题,意在考量候选人的头脑体式格局和处理问题的才能,以及把他思索的历程论述清晰的表达才能。这三种才能,每每比运用过某些框架的履历,更让我看中。

这道题的回复思绪,实在就是能够经由过程发掘源码,去完成功用。别的也能够经由过程海量地查找材料,发明原生js的完成体式格局,但这条路没有直接发掘源码来得快。在碰到现实的营业问题的时刻,参考源码的道理和写法,每每能更快地处理问题。

这是我本身对这道问题,给出的答案。

一点点思索

昨天的案例,引发了我的一连串思索:

当代框架确实降低了前端入门的门坎,提高了开辟效力。

然则,在运用这些框架的历程当中,我们究竟学到了什么?

脱离了框架和它的API,我们脑海中还剩下些什么?

以至于,当下一个更新更棒的框架涌现的时刻,我们是否能够用已学到的学问,协助本身更迅速地上手?

知其然,并知其所以然,进修一切的学问都应当有这类探究精力。我们不仅仅是代码的搬运工。意会这些深层次的道理,比起仅仅熟练地控制一门框架,要有用很多。

PS:迎接关注我的民众号 “超哥前端小栈”,交换更多的主意与手艺。
《「读懂源码系列1」还在恐惊读源码?看完这篇就不怕了》

    原文作者:micherwa
    原文地址: https://segmentfault.com/a/1190000017834617
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞