最后
小编的一位同事在校期间连续三年参加ACM-ICPC竞赛。从参赛开始,原计划每天刷一道算法题,实际上每天有时候不止一题,一年最终完成了 600+:
凭借三年刷题经验,他在校招中很快拿到了各大公司的offer。
入职前,他把他的刷题经验总结成1121页PDF书籍,作为礼物赠送给他的学弟学妹,希望同学们都能在最短时间内掌握校招常见的算法及解题思路。
整本书,我仔细看了一遍,作者非常细心地将常见核心算法题和汇总题拆分为4个章节。
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
而对于有时间的同学,作者还给出了他结合众多数据结构算法书籍,挑选出的一千多道题的解题思路和方法,以供有需要的同学慢慢研究。
组件结构化
按照一定的结构组织,使得组件便于理解。
为什么?
-
导出一个清晰、组织有序的组件,使得代码易于阅读和理解。同时也便于标准化。
-
按首字母排序 properties、data、computed、watches 和 methods 使得这些对象内的属性便于查找。
-
合理组织,使得组件易于阅读。(name; extends; props, data 和 computed; components; watch 和 methods; lifecycle methods 等)。
-
使用
name
属性。借助于 vue devtools 可以让你更方便的测试。 -
合理的 CSS 结构,如 BEM 或 rscss - 详情?。
-
使用单文件 .vue 文件格式来组件代码。
怎么做?
组件结构化
↑ 回到目录
组件事件命名
Vue.js 提供的处理函数和表达式都是绑定在 ViewModel 上的,组件的每一个事件都应该按照一个好的命名规范来,这样可以避免不少的开发问题,具体可见如下 为什么。
为什么?
-
开发者可以随意给事件命名,即使是原生事件的名字,这样会带来迷惑性。
-
过于宽松的事件命名可能与 DOM 模板不兼容。
怎么做?
-
事件名也使用连字符命名。
-
一个事件的名字对应组件外的一组意义操作,如:upload-success、upload-error 以及 dropzone-upload-success、dropzone-upload-error (如果需要前缀的话)。
-
事件命名应该以动词(如 client-api-load) 或是 名词(如 drive-upload-success)结尾。(出处)
↑ 回到目录
避免 this.$parent
Vue.js 支持组件嵌套,并且子组件可访问父组件的上下文。访问组件之外的上下文违反了基于模块开发的第一原则。因此你应该尽量避免使用 this.$parent
。
为什么?
-
组件必须相互保持独立,Vue 组件也是。如果组件需要访问其父层的上下文就违反了该原则。
-
如果一个组件需要访问其父组件的上下文,那么该组件将不能在其它上下文中复用。
怎么做?
-
通过 props 将值传递给子组件。
-
通过 props 传递回调函数给子组件来达到调用父组件方法的目的。
-
通过在子组件触发事件来通知父组件。
↑ 回到目录
谨慎使用 this.$refs
Vue.js 支持通过 ref
属性来访问其它组件和 HTML 元素。并通过 this.$refs
可以得到组件或 HTML 元素的上下文。在大多数情况下,通过 this.$refs
来访问其它组件的上下文是可以避免的。在使用的的时候你需要注意避免调用了不恰当的组件 API,所以应该尽量避免使用 this.$refs
。
为什么?
-
组件必须是保持独立的,如果一个组件的 API 不能够提供所需的功能,那么这个组件在设计、实现上是有问题的。
-
组件的属性和事件必须足够的给大多数的组件使用。
怎么做?
-
提供良好的组件 API。
-
总是关注于组件本身的目的。
-
拒绝定制代码。如果你在一个通用的组件内部编写特定需求的代码,那么代表这个组件的 API 不够通用,或者你可能需要一个新的组件来应对该需求。
-
检查所有的 props 是否有缺失的,如果有提一个 issue 或是完善这个组件。
-
检查所有的事件。子组件向父组件通信一般是通过事件来实现的,但是大多数的开发者更多的关注于 props 从忽视了这点。
-
Props向下传递,事件向上传递!。以此为目标升级你的组件,提供良好的 API 和 独立性。
-
当遇到 props 和 events 难以实现的功能时,通过
this.$refs
来实现。 -
当需要操作 DOM 无法通过指令来做的时候可使用
this.$ref
而不是JQuery
、document.getElement*
、document.queryElement
。
<range :max=“max”
:min=“min”
@current-value=“currentValue”
:step=“1”>
Basic Modal
<button class=“primary” @click=“$refs.basicModal.hide()”>Close
<button @click=“$refs.basicModal.open()”>Open modal
<range :max=“max”
:min=“min”
ref=“range”
:step=“1”>
↑ 回到目录
使用组件名作为样式作用域空间
Vue.js 的组件是自定义元素,这非常适合用来作为样式的根作用域空间。可以将组件名作为 CSS 类的命名空间。
为什么?
-
给样式加上作用域空间可以避免组件样式影响外部的样式。
-
保持模块名、目录名、样式根作用域名一样,可以很好的将其关联起来,便于开发者理解。
怎么做?
使用组件名作为样式命名的前缀,可基于 BEM 或 OOCSS 范式。同时给 style 标签加上 scoped 属性。加上 scoped 属性编译后会给组件的 class 自动加上唯一的前缀从而避免样式的冲突。
↑ 回到目录
提供组件 API 文档
使用 Vue.js 组件的过程中会创建 Vue 组件实例,这个实例是通过自定义属性配置的。为了便于其他开发者使用该组件,对于这些自定义属性即组件API应该在 README.md
文件中进行说明。
为什么?
-
良好的文档可以让开发者比较容易的对组件有一个整体的认识,而不用去阅读组件的源码,也更方便开发者使用。
-
组件配置属性即组件的 API,对于组件的用户来说他们更感兴趣的是 API 而不是实现原理。
-
正式的文档会告诉开发者组件 API 变更以及向后的兼容性情况。
-
README.md
是标准的我们应该首先阅读的文档文件。代码托管网站(GitHub、Bitbucket、Gitlab 等)会默认在仓库中展示该文件作为仓库的介绍。
怎么做?
在模块目录中添加 README.md
文件:
range-slider/
├── range-slider.vue
├── range-slider.less
└── README.md
在 README 文件中说明模块的功能以及使用场景。对于 vue 组件来说,比较有用的描述是组件的自定义属性即 API 的描述介绍。
Range slider
============
功能
–
range slider 组件可通过拖动的方式来设置一个给定范围内的数值。
该模块使用 noUiSlider 来实现跨浏览器和 touch 功能的支持。
如何使用
<range-slider>
支持如下的自定义属性:
| attribute | type | description |
| — | — | — |
| min
| Number | 可拖动的最小值. |
| max
| Number | 可拖动的最大值. |
| values
| Number[] optional | 包含最大值和最小值的数组. 如. values="[10, 20]"
. Defaults to [opts.min, opts.max]
. |
| step
| Number optional | 增加减小的数值单位,默认为 1. |
| on-slide
| Function optional | 用户拖动开始按钮或者结束按钮时的回调函数,函数接受 (values, HANDLE)
格式的参数。如:on-slide={ updateInputs }
, component.updateInputs = (values, HANDLE) => { const value = values[HANDLE]; }
. |
| on-end
| Function optional | 当用户停止拖动时触发的回调函数,函数接受 (values, HANDLE)
格式的参数。 |
如需要自定义 slider 的样式可参考 noUiSlider 文档
↑ 回到目录
提供组件 demo
添加 index.html
文件作为组件的 demo 示例,并提供不同配置情况的效果,说明组件是如何使用的。
为什么?
-
demo 可以说明组件是独立可使用的。
-
demo 可以让开发者预览组件的功能效果。
-
demo 可以展示组件各种配置参数下的功能。
↑ 回到目录
对组件文件进行代码校验
代码校验可以保持代码的统一性以及追踪语法错误。.vue 文件可以通过使用 eslint-plugin-html
插件来校验代码。你可以通过 vue-cli
来开始你的项目,vue-cli
默认会开启代码校验功能。
为什么?
-
保证所有的开发者使用同样的编码规范。
-
更早的感知到语法错误。
怎么做?
为了校验工具能够校验 *.vue
文件,你需要将代码编写在 <script>
标签中,并使组件表达式简单化,因为校验工具无法理解行内表达式,配置校验工具可以访问全局变量 vue
和组件的 props
。
ESLint
ESLint 需要通过 ESLint HTML 插件来抽取组件中的代码。
通过 .eslintrc
文件来配置 ESlint,这样 IDE 可以更好的理解校验配置项:
{
“extends”: “eslint:recommended”,
“plugins”: [“html”],
“env”: {
“browser”: true
},
“globals”: {
“opts”: true,
“vue”: true
}
}
运行 ESLint
eslint src/**/*.vue
JSHint
JSHint 可以解析 HTML(使用 --extra-ext
命令参数)和抽取代码(使用 --extract=auto
命令参数)。
通过 .jshintrc
文件来配置 ESlint,这样 IDE 可以更好的理解校验配置项。
{
“browser”: true,
“predef”: [“opts”, “vue”]
}
运行 JSHint
jshint --config modules/.jshintrc --extra-ext=html --extract=auto modules/
注:JSHint 不接受 vue
扩展名的文件,只支持 html
。
只在需要时创建组件
为什么?
Vue.js 是一个基于组件的框架。如果你不知道何时创建组件可能会导致以下问题:
-
如果组件太大, 可能很难重用和维护;
-
如果组件太小,你的项目就会(因为深层次的嵌套而)被淹没,也更难使组件间通信;
怎么做?
-
始终记住为你的项目需求构建你的组件,但是你也应该尝试想到它们能够从中脱颖而出(独立于项目之外)。如果它们能够在你项目之外工作,就像一个库那样,就会使得它们更加健壮和一致。
-
尽可能早地构建你的组件总是更好的,因为这样使得你可以在一个已经存在和稳定的组件上构建你的组件间通信(props & events)。
规则
-
首先,尽可能早地尝试构建出诸如模态框、提示框、工具条、菜单、头部等这些明显的(通用型)组件。总之,你知道的这些组件以后一定会在当前页面或者是全局范围内需要。
-
第二,在每一个新的开发项目中,对于一整个页面或者其中的一部分,在进行开发前先尝试思考一下。如果你认为它有一部分应该是一个组件,那么就创建它吧。
-
最后,如果你不确定,那就不要。避免那些“以后可能会有用”的组件污染你的项目。它们可能会永远的只是(静静地)待在那里,这一点也不聪明。注意,一旦你意识到应该这么做,最好是就把它打破,以避免与项目的其他部分构成兼容性和复杂性。
↑ 回到目录
尽可能使用 mixins
为什么?
Mixins 封装可重用的代码,避免了重复。如果两个组件共享有相同的功能,则可以使用 mixin。通过 mixin,你可以专注于单个组件的任务和抽象的通用代码。这有助于更好地维护你的应用程序。
怎么做?
假设你有一个移动端和桌面端的菜单组件,它们共享一些功能。我们可以抽象出这两个组件的核心功能到一个 mixin 中,例如:
const MenuMixin = {
data () {
return {
language: ‘EN’
}
},
methods: {
changeLanguage () {
if (this.language === ‘DE’) this.$set(this, ‘language’, ‘EN’)
if (this.language === ‘EN’) this.$set(this, ‘language’, ‘DE’)
}
}
}
export default MenuMixin
要使用 mixin,只需将其导入到两个组件中(我只展示移动组件)。
↑ 回到目录
如何提供帮助?
Fork 和提 PR 以帮助我们改进或者可以给我们提 Issue。
总结
为了帮助大家更好温习重点知识、更高效的准备面试,特别整理了《前端工程师面试手册》电子稿文件。
内容包括html,css,JavaScript,ES6,计算机网络,浏览器,工程化,模块化,Node.js,框架,数据结构,性能优化,项目等等。
包含了腾讯、字节跳动、小米、阿里、滴滴、美团、58、拼多多、360、新浪、搜狐等一线互联网公司面试被问到的题目,涵盖了初中级前端技术点。
前端面试题汇总
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
JavaScript
性能
linux