总结
面试前要精心做好准备,简历上写的知识点和原理都需要准备好,项目上多想想难点和亮点,这是面试时能和别人不一样的地方。
还有就是表现出自己的谦虚好学,以及对于未来持续进阶的规划,企业招人更偏爱稳定的人。
万事开头难,但是程序员这一条路坚持几年后发展空间还是非常大的,一切重在坚持。
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
前端面试题汇总
JavaScript
前端资料汇总
在 new Vue() 中,data 是可以作为一个对象进行操作的,然而在 component 中,data 只能以函数的形式存在,不能直接将对象赋值给它。
当data选项是一个函数的时候,每个实例可以维护一份被返回对象的独立的拷贝,这样各个实例中的data不会相互影响,是独立的。
一、Vuex就是一个仓库,仓库里面放了很多对象。其中state就是数据源存放地,对应于与一般Vue对象里面的data
二、state里面存放的数据是响应式的,Vue组件从store中读取数据,若是store中的数据发生改变,依赖这个数据的组件也会发生更新
三、它通过mapState把全局的 state 和 getters 映射到当前组件的 computed 计算属性中
Vue为MVVM框架,当数据模型data变化时,页面视图会得到响应更新,其原理对data的getter/setter方法进行拦截(Object.defineProperty或者Proxy),利用发布订阅的设计模式,在getter方法中进行订阅,在setter方法中发布通知,让所有订阅者完成响应。
在响应式系统中,Vue会为数据模型data的每一个属性新建一个订阅中心作为发布者,而监听器watch、计算属性computed、视图渲染template/render三个角色同时作为订阅者,对于监听器watch,会直接订阅观察监听的属性,对于计算属性computed和视图渲染template/render,如果内部执行获取了data的某个属性,就会执行该属性的getter方法,然后自动完成对该属性的订阅,当属性被修改时,就会执行该属性的setter方法,从而完成该属性的发布通知,通知所有订阅者进行更新。
计算属性computed和监听器watch都可以观察属性的变化从而做出响应,不同的是:
计算属性computed更多是作为缓存功能的观察者,它可以将一个或者多个data的属性进行复杂的计算生成一个新的值,提供给渲染函数使用,当依赖的属性变化时,computed不会立即重新计算生成新的值,而是先标记为脏数据,当下次computed被获取时候,才会进行重新计算并返回。
而监听器watch并不具备缓存性,监听器watch提供一个监听函数,当监听的属性发生变化时,会立即执行该函数。
beforeCreate:是new Vue()之后触发的第一个钩子,在当前阶段data、methods、computed以及watch上的数据和方法都不能被访问。
created:在实例创建完成后发生,当前阶段已经完成了数据观测,也就是可以使用数据,更改数据,在这里更改数据不会触发updated函数。可以做一些初始数据的获取,在当前阶段无法与Dom进行交互,如果非要想,可以通过vm.$nextTick来访问Dom。
beforeMount:发生在挂载之前,在这之前template模板已导入渲染函数编译。而当前阶段虚拟Dom已经创建完成,即将开始渲染。在此时也可以对数据进行更改,不会触发updated。
mounted:在挂载完成后发生,在当前阶段,真实的Dom挂载完毕,数据完成双向绑定,可以访问到Dom节点,使用$refs属性对Dom进行操作。
beforeUpdate:发生在更新之前,也就是响应式数据发生更新,虚拟dom重新渲染之前被触发,你可以在当前阶段进行更改数据,不会造成重渲染。
updated:发生在更新完成之后,当前阶段组件Dom已完成更新。要注意的是避免在此期间更改数据,因为这可能会导致无限循环的更新。
beforeDestroy:发生在实例销毁之前,在当前阶段实例完全可以被使用,我们可以在这时进行善后收尾工作,比如清除计时器。
destroyed:发生在实例销毁之后,这个时候只剩下了dom空壳。组件已被拆解,数据绑定被卸除,监听被移出,子实例也统统被销毁。
一个组件可能在很多地方使用,也就是会创建很多个实例,如果data是一个对象的话,对象是引用类型,一个实例修改了data会影响到其他实例,所以data必须使用函数,为每一个实例创建一个属于自己的data,使其同一个组件的不同实例互不影响。
父子组件通信
父组件 -> 子组件:prop
子组件 -> 父组件: o n / on/ on/emit
获取组件实例:使用 p a r e n t / parent/ parent/children,$refs.xxx,获取到实例后直接获取属性数据或调用组件方法
兄弟组件通信
Event Bus:每一个Vue实例都是一个Event Bus,都支持 o n / on/ on/emit,可以为兄弟组件的实例之间new一个Vue实例,作为Event Bus进行通信。
Vuex:将状态和方法提取到Vuex,完成共享
跨级组件通信
使用provide/inject
Event Bus:同兄弟组件Event Bus通信
Vuex:将状态和方法提取到Vuex,完成共享
每一个Vue实例都是一个Event Bus,当子组件被创建的时候,父组件将事件传递给子组件,子组件初始化的时候是有 o n 方 法 将 事 件 注 册 到 内 部 , 在 需 要 的 时 候 使 用 on方法将事件注册到内部,在需要的时候使用 on方法将事件注册到内部,在需要的时候使用emit触发函数,而对于原生native事件,使用addEventListener绑定到真实的DOM元素上。
低耦合。视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的"View"上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。
可重用性。你可以把一些视图逻辑放在一个ViewModel里面,让很多view重用这段视图逻辑。
独立开发。开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计。
可测试。界面素来是比较难于测试的,而现在测试可以针对ViewModel来写
1.与AngularJS的区别
相同点:
都支持指令:内置指令和自定义指令。
都支持过滤器:内置过滤器和自定义过滤器。
都支持双向数据绑定。
都不支持低端浏览器。
不同点:
1.AngularJS的学习成本高,比如增加了Dependency Injection特性,而Vue.js本身提供的API都比较简单、直观。
2.在性能上,AngularJS依赖对数据做脏检查,所以Watcher越多越慢。
Vue.js使用基于依赖追踪的观察并且使用异步队列更新。所有的数据都是独立触发的。 对于庞大的应用来说,这个优化差异还是比较明显的。
2.与React的区别
相同点:
1.React采用特殊的JSX语法,Vue.js在组件开发中也推崇编写.vue特殊文件格式,对文件内容都有一些约定,两者都需要编译后使用。
2.中心思想相同:一切都是组件,组件实例之间可以嵌套。
3.都提供合理的钩子函数,可以让开发者定制化地去处理需求。
4.都不内置AJAX,Route等功能到核心包,而是以插件的方式加载。 5.在组件开发中都支持mixins的特性。
不同点:
React依赖Virtual DOM,而Vue.js使用的是DOM模板。React采用的Virtual DOM会对渲染出来的结果做脏检查。
Vue.js在模板中提供了指令,过滤器等,可以非常方便,快捷地操作DOM。
在模板中放入太多的逻辑会让模板过重且难以维护,在需要对数据进行复杂处理,且可能多次使用的情况下,尽量采取计算属性的方式。好处:①使得数据处理结构清晰;②依赖于数据,数据更新,处理结果自动更新;③计算属性内部this指向vm实例;④在template调用时,直接写计算属性名即可;⑤常用的是getter方法,获取数据,也可以使用set方法改变数据;⑥相较于methods,不管依赖的数据变不变,methods都会重新计算,但是依赖数据不变的时候computed从缓存中获取,不会重新计算。
优点: Vue的目标是通过尽可能简单的 API实现响应的数据绑定和组合的视图组件,核心是一个响应的数据绑定系统。MVVM、数据驱动、组件化、轻量、简洁、高效、快速、模块友好;即第一次就将所有的东西都加载完成,因此,不会导致页面卡顿。
缺点: 不支持低版本的浏览器,最低只支持到IE9;不利于SEO的优化(如果要支持SEO,建议通过服务端来进行渲染组件);第一次加载首页耗时相对长一些;不可以使用浏览器的导航按钮需要自行实现前进、后退。
14.active-class是哪个组件的属性?嵌套路由怎么定义?
vue-router模块的router-link组件的属性。
嵌套路由:
嵌套路由顾名思义就是路由的多层嵌套。
重构router/index.js的路由配置,需要使用children数组来定义子路由 ,路由定义:
{
path: ‘/me’,
name: ‘Me’,
component: Me,
children: [
{
path: ‘collection’,
name: ‘Collection’,
component: Collection
},
{
path: ‘trace’,
name: ‘Trace’,
component: Trace
}
]
}
以“/”开头的嵌套路径会被当作根路径,所以子路由上不用加“/”;
在生成路由时,主路由上的path会被自动添加到子路由之前,所以子路由上的path不用在重新声明主路由上的path了。
在外层路由组件中,如下写法。
我的收藏
我的足迹
由于篇幅有限,只能分享部分面试题,更多面试题及答案可以【点击我】阅读下载哦~无偿分享给大家,算是一个感恩回馈吧
渐进式网页应用,PWA 应该具有一下特性:
渐进式:能确保每个用户都能打开网页响应式:PC,手机,平板,不管哪种格式,网页格式都能完美适配
2.离线应用:支持用户在没网的条件下也能打开网页,这里就需要 Service Worker 的帮助
3.APP 化:能够像 APP 一样和用户进行交互
4.常更新:一旦 Web 网页有什么改动,都能立即在用户端体现出来
5.安全:安全第一,给自己的网站加上一把绿锁–HTTPS
6.可搜索:能够被引擎搜索到
7.推送:做到在不打开网页的前提下,推送新的消息
8.可安装:能够将 Web 想 APP 一样添加到桌面
9.可跳转:只要通过一个连接就可以跳转到你的 Web 页面
slot又名插槽,是Vue的内容分发机制,组件内部的模板引擎使用slot元素作为承载分发内容的出口。插槽slot是子组件的一个模板标签元素,而这一个标签元素是否显示,以及怎么显示是由父组件决定的。
slot又分三类,默认插槽,具名插槽和作用域插槽。
默认插槽:又名匿名查抄,当slot没有指定name属性值的时候一个默认显示插槽,一个组件内只有有一个匿名插槽。
具名插槽:带有具体名字的插槽,也就是带有name属性的slot,一个组件可以出现多个具名插槽。
作用域插槽:默认插槽、具名插槽的一个变体,可以是匿名插槽,也可以是具名插槽,该插槽的不同点是在子组件渲染作用域插槽时,可以将子组件内部的数据传递给父组件,让父组件根据子组件的传递过来的数据决定如何渲染该插槽。
实现原理:当子组件vm实例化时,获取到父组件传入的slot标签的内容,存放在vm. s l o t 中 , 默 认 插 槽 为 v m . slot中,默认插槽为vm. slot中,默认插槽为vm.slot.default,具名插槽为vm. s l o t . x x x , x x x 为 插 槽 名 , 当 组 件 执 行 渲 染 函 数 时 候 , 遇 到 s l o t 标 签 , 使 用 slot.xxx,xxx 为插槽名,当组件执行渲染函数时候,遇到slot标签,使用 slot.xxx,xxx为插槽名,当组件执行渲染函数时候,遇到slot标签,使用slot中的内容进行替换,此时可以为插槽传递数据,若存在数据,则可称该插槽为作用域插槽。
vue中的模板template无法被浏览器解析并渲染,因为这不属于浏览器的标准,不是正确的HTML语法,所有需要将template转化成一个JavaScript函数,这样浏览器就可以执行这一个函数并渲染出对应的HTML元素,就可以让视图跑起来了,这一个转化的过程,就成为模板编译。
模板编译又分三个阶段,解析parse,优化optimize,生成generate,最终生成可执行函数render。
parse阶段:使用大量的正则表达式对template字符串进行解析,将标签、指令、属性等转化为抽象语法树AST。
optimize阶段:遍历AST,找到其中的一些静态节点并进行标记,方便在页面重渲染的时候进行diff比较时,直接跳过这一些静态节点,优化runtime的性能。
generate阶段:将最终的AST转化为render函数字符串。
对于 Vue 组件来说,模板编译只会在组件实例化的时候编译一次,生成渲染函数之后在也不会进行编译。因此,编译对组件的 runtime 是一种性能损耗。
而模板编译的目的仅仅是将template转化为render function,这个过程,正好可以在项目构建的过程中完成,这样可以让实际组件在 runtime 时直接跳过模板渲染,进而提升性能,这个在项目构建的编译template的过程,就是预编译。
对于 runtime 来说,只需要保证组件存在 render 函数即可,而我们有了预编译之后,我们只需要保证构建过程中生成 render 函数就可以。
在 webpack 中,我们使用vue-loader编译.vue文件,内部依赖的vue-template-compiler模块,在 webpack 构建过程中,将template预编译成 render 函数。
与 react 类似,在添加了jsx的语法糖解析器babel-plugin-transform-vue-jsx之后,就可以直接手写render函数。
所以,template和jsx的都是render的一种表现形式,不同的是:
JSX相对于template而言,具有更高的灵活性,在复杂的组件中,更具有优势,而 template 虽然显得有些呆滞。但是 template 在代码结构上更符合视图与逻辑分离的习惯,更简单、更直观、更好维护。
Virtual DOM 是 DOM 节点在 JavaScript 中的一种抽象数据结构,之所以需要虚拟DOM,是因为浏览器中操作DOM的代价比较昂贵,频繁操作DOM会产生性能问题。虚拟DOM的作用是在每一次响应式数据发生变化引起页面重渲染时,Vue对比更新前后的虚拟DOM,匹配找出尽可能少的需要更新的真实DOM,从而达到提升性能的目的。
在新老虚拟DOM对比时
首先,对比节点本身,判断是否为同一节点,如果不为相同节点,则删除该节点重新创建节点进行替换
如果为相同节点,进行patchVnode,判断如何对该节点的子节点进行处理,先判断一方有子节点一方没有子节点的情况(如果新的children没有子节点,将旧的子节点移除)
比较如果都有子节点,则进行updateChildren,判断如何对这些新老节点的子节点进行操作(diff核心)。
匹配时,找到相同的子节点,递归比较子节点
在diff中,只对同层的子节点进行比较,放弃跨级的节点比较,使得时间复杂从O(n^3)降低值O(n),也就是说,只有当新旧children都为多个子节点时才需要用核心的Diff算法进行同层级比较。
Vue 编码基础
2.1.1. 组件规范
2.1.2. 模板中使用简单的表达式
2.1.3 指令都使用缩写形式
2.1.4 标签顺序保持一致
2.1.5 必须为 v-for 设置键值 key
2.1.6 v-show 与 v-if 选择
2.1.7 script 标签内部结构顺序
2.1.8 Vue Router 规范
Vue 项目目录规范
2.2.1 基础
2.2.2 使用 Vue-cli 脚手架
2.2.3 目录说明
2.2.4注释说明
2.2.5 其他