看到掘金里有不少水文…那…我也就有胆子来灌水了[不是]
然后…本文没啥实际用处,而且弄得比较仓促,有些虎头蛇尾;加之我比较水,就…
其实不过是一个根据 commit 、 社区讨论过程理解源码的的一个碎片化记录,面试等情况是不会考这些的。
在我们看源码的时候,有时会惊讶于:作者是怎么想到这个问题的?其实若跟踪其提交记录、讨论记录,也许能够帮助我们理解问题的发现与解决,见证作者的成长[doge]。
以上为本篇正文,感谢各位看官观摩,现在可以 Alt + F4 了[划掉]
咳…其实是某群里有位小伙伴问了一个问题,截图对应的代码如下:
if ((key in vm) && isReserved(key)) {warn(`Method "${key}" conflicts with an existing Vue instance method. ` +`Avoid defining component methods that start with _ or $.`)}
}
vm[key] = typeof methods[key] !== 'function' ? noop : bind(methods[key], vm)
问道:
请问一下,isReserved是判断什么的
这明显是 Vue 的提示,所以去 Vue 的仓库(v2.6) 搜了一下这段代码所在的位置:
src\core\instance\state.js
function initMethods (vm: Component, methods: Object) {const props = vm.$options.propsfor (const key in methods) {if (process.env.NODE_ENV !== 'production') {if (typeof methods[key] !== 'function') {warn(`Method "${key}" has type "${typeof methods[key]}" in the component definition. ` +`Did you reference the function correctly?`,vm)}if (props && hasOwn(props, key)) {warn(`Method "${key}" has already been defined as a prop.`,vm)}if ((key in vm) && isReserved(key)) {warn(`Method "${key}" conflicts with an existing Vue instance method. ` +`Avoid defining component methods that start with _ or $.`)}}vm[key] = typeof methods[key] !== 'function' ? noop : bind(methods[key], vm)}
}
这个方法仅判断开头是否为 $ 或 _
通过警告内容可知,触犯该规则的三个条件:
1.当前为非生产模式,一般来说是本地开发模式才会执行这些警告。这十分容易理解:类似于这些警报提示是面向开发者的,而非面向最终用户;
2.新的 key 已经在 Vue 实例中存在,接下来会覆盖已有的项目;
3.大家定义私有方法时喜欢以 $ 或 _ 开头,但 Vue 中恰恰也是以这俩作为私有方法的开头内容的,可能会引发冲突,所以需要警示开发者尽量不要这么做,以免造成不良影响,规范后续行为。这便是 isReserved 的判断。
可以这么理解:
isReserved 的作用是,在 Vue 实例发生命名冲突时(第2点),提供一种参考建议,来帮助开发者接下来规避与 Vue 已有方法的冲突。
插曲: 为了更好地理解其中缘由,我们可以了解一下其提交历史。VSCode 的话,可以配合 GitLens 查看该行对应的 commit.
Vue 2 仓库中,src/core/util/lang.js
有这个 isReserved 方法 注释内容为:
Check if a string starts with $ or _
从该文件第一次创建时就有了,对应的 commit 信息为 restructure,这里不容易找线索。
到调用处 src/core/instance/state.js
上对应的commit 为:
chore:warn methods that conflict with internals. close #6312
顺着该 commit 打开对应的 issue:
可见是讨论命名冲突的问题,不过没有讨论出很好的结果,只是一个开始。
后来尤大调整了这个策略,见该比对: github.com/vuejs/vue/c…
也就是现在的样子。
在该 issue 的最后,其他的 issue 提及了该问题,顺着里面继续看 #7070 www.github.com/vuejs/vue/i…
这讨论算是完结了。
另: 相对应的,从风格指南中有关于 $ 和 _ 的使用约定: cn.vuejs.org/v2/style-gu…
对于这种私有情况,约定是以 $_ 为开头,这样就必然可以规避开头的报错了。
以上便是结合多种方式理解源码的一个小栗子。没什么难度,只是需要多点耐心,相信大家都能搞定的~
最后,以此也能发现严格要求 commit 格式的好处:方便其他团队成员追溯。提交时一般会使用 commit lint 进行预先校验,相关文章汗牛充栋,本文就不赘述了。