前端面试题目合集

抱歉,这篇博客是很早写的,并且决定了不再更新,是因为github上有很多整理的很好的面试图谱

我列举下我看过的比较好的几个(按质量排序,最好的放前面)

https://yuchengkai.cn/docs/zh/ (这个是我见过最好的前端面试图谱了)

https://github.com/yangshun/tech-interview-handbook

https://github.com/ElemeFE/node-interview

发现面试题目已经过于模板化,基本上都是那些题目,故作次总结、以便后续遇到能够答得更好。

打算分为四个部分:H5+CSS3、JS、计算机网络、框架(Vue)、数据结构与算法

H5+CSS3

1.谈谈你对盒子模型的理解。类似问题:IE盒子模型和标准盒子模型有什么区别?

一个盒子一般由content(实际内容)、padding(填充)、border(边框)、margin(外边距)组成。

注意:margin有个合并问题,当两个垂直margin遇到后会合并,合并后的margin的高度等于其中的较大者。

ie盒子模型与标准w3c盒子模型的区别是:前者content的宽度和高度包括了border和padding,后者不包括。

也就是当我们给一个盒子设置了宽高后,ie盒子占据的总宽度是:width+2*marigin。标准w3c盒子占据的总宽度是:width+2*padding+2*border+2*margin.

一般标准模式下(即有<!DOCTYPE html>),浏览器按w3c标准解析执行代码,使用的是标准w3c盒子模型。

怪异模式下(无<!DOCTYPE html>),浏览器使用自己的标准解析执行代码,ie系列(ie9除外)使用的是ie盒子模型。

当然为了兼容,为了实现跨浏览器css,一般都是使用标准模式。

此外,为了开发方便,css3推出了 一个属性box-sizing,其中border-box值表示在内容区域的宽度高度里绘制边框和padding(类似ie盒子模型)

content-box值表示在内容区域外的绘制边框和padding,inherit值表示继承父盒子的属性。

2.五大浏览器的内核及css属性前缀。

IE浏览器:Trident内核   前缀:-ms-

Chrom浏览器:Blink内核(WebKit内核的一个分支) 前缀:-webkit-

FireFox浏览器:Gecko内核 前缀:-moz-

Safari浏览器:WebKit2内核(WebKit内核的一个分支) 前缀:-webkit

Opera浏览器:Presto内核=》Blink内核 前缀:-o-

注:css属性中的前缀只是为了兼容老版本的浏览器,也就是兼容老版本浏览器的内核。

3.rem与em的区别,rem的优缺点

rem是根据根节点<html>元素的字体大小来计算的。

em是根据自身元素的字体大小来计算的(因为自己字体大小没有设置,所以是继承父元素的字体大小)

rem优点:计算方便。

rem缺点:在app中native界面与web界面搭配在一起时,rem在不同屏幕上适配与native界面适配不一致问题。

4.懒加载怎么实现?

  • 先将img标签中的src链接设为同一张图片(空白图片),将其真正的图片地址存储再img标签的自定义属性中(比如data-src)。当js监听到该图片元素进入可视窗口时,即将自定义属性中的地址存储到src属性中,达到懒加载的效果。
  • 这样做能防止页面一次性向服务器响应大量请求导致服务器响应慢,页面卡顿或崩溃等问题

5.低版本浏览器不支持HTML5标签怎么解决?

添加shiv脚本就行:

<!--[if lt IE9]> 
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->

6.link和@import引入css的区别?

  区别1:link是XHTML标签,除了加载CSS外,还可以定义RSS等其他事务;@import属于CSS范畴,只能加载CSS。

  区别2:link引用CSS时,在页面载入时同时加载;@import需要页面网页完全载入以后加载。

  区别3:link是XHTML标签,无兼容问题;@import是在CSS2.1提出的,低版本的浏览器不支持。

  区别4:ink支持使用Javascript控制DOM去改变样式;而@import不支持。

7.cookie、sessionStorage、localStorage的异同。

 

三者的应用场景

因为考虑到每个 HTTP 请求都会带着 Cookie 的信息,所以 Cookie 当然是能精简就精简啦,比较常用的一个应用场景就是判断用户是否登录。针对登录过的用户,服务器端会在他登录时往 Cookie 中插入一段加密过的唯一辨识单一用户的辨识码,下次只要读取这个值就可以判断当前用户是否登录啦。曾经还使用 Cookie 来保存用户在电商网站的购物车信息,如今有了 localStorage,似乎在这个方面也可以给 Cookie 放个假了~(因为http是面向无状态的协议,所以需要cookie来储存一些“状态”)

而另一方面 localStorage 接替了 Cookie 管理购物车的工作,同时也能胜任其他一些工作。比如HTML5游戏通常会产生一些本地数据,localStorage 也是非常适用的。如果遇到一些内容特别多的表单,为了优化用户体验,我们可能要把表单页面拆分成多个子页面,然后按步骤引导用户填写。这时候 sessionStorage 的作用就发挥出来了。

8.CS、JS放置位置与前端性能关系?

 以上四步并非严格按顺序执行,往往第一步还没完成,第二步和第三步就已经开始了。所以,会看到这种情况:网页的HTML代码还没下载完,但浏览器已经显示出内容了。

加载外部脚本时,浏览器会暂停页面渲染,等待脚本下载并执行完成后,再继续渲染。原因是JavaScript可以修改DOM(比如使用document.write方法),所以必须把控制权让给它,否则会导致复杂的线程竞赛的问题。

如果外部脚本加载时间很长(比如一直无法完成下载),就会造成网页长时间失去响应,浏览器就会呈现“假死”状态,这被称为“阻塞效应”。

为了避免这种情况,较好的做法是将<script>标签都放在页面底部(</body>前),而不是头部。

  1. 这样即使遇到脚本失去响应,网页主体的渲染也已经完成了,用户至少可以看到内容,而不是面对一张空白的页面。如果某些脚本代码非常重要,一定要放在页面头部的话,最好直接将代码嵌入页面,而不是连接外部脚本文件,这样能缩短加载时间。
  1. 将脚本文件都放在网页尾部加载,还有一个好处。在DOM结构生成之前就调用DOM,JavaScript会报错,如果脚本都在网页尾部加载,就不存在这个问题,因为这时DOM肯定已经生成了。

此外<script>标签使用defer属性和async属性可以并行下载脚本文件,不阻塞渲染,不过async属性不能保证脚本的执行顺序。

CSS放在前端是页面渲染时首先是根据DOM结构生成一个DOM树然后加上CSS样式生成一个渲染树,

如果CSS放在后面可能页面会出现闪跳的感觉,或者是白屏或者布局混乱样式很丑直到CSS加载完成,所以CSS标签应该放到头部(<head></head>之间)

9.JS动画的时间间隔设置为多少比较好?

多数显示器默认频率是60Hz,即1秒刷新60次,所以理论上最小间隔为1/60*1000ms = 16.7ms

10.css实现三角形、圆形、梯形、椭圆形、平行四边形、气泡框、自适应正方形

http://www.cnblogs.com/wuguanglin/p/interestingCSS.html

11.标准模式与怪异模式。

在标准模式下,浏览器按照HTML与CSS标准对文档进行解析和渲染;而在怪异模式下,浏览器则按照旧有的非标准的实现方式对文档进行解析和渲染。

浏览器主要通过文档类型来决定使用那张模式,没有文档类型声明或者文档类型声明错误的使用怪异模式。

标准模式和怪异模式的区别:

  • 盒模型的处理差异。(标准盒子/IE盒子)
  • 行内元素的垂直对齐。(基线/底线)

12.XHTML与HTML的区别

  • XHTML 元素必须被正确地嵌套。
  • XHTML 元素必须被关闭。
  • 标签名必须用小写字母。
  • XHTML 文档必须拥有根元素。

13.使用data-的好处。

可以添加自定义属性,提供了更多操作的可能

14.meta标签

<meta> 元素可提供有关页面的元信息(meta-information),比如针对搜索引擎和更新频度的描述和关键词。

主要的三个为属性http-equiv、name、content.当然定义编码格式的时候可以直接<meta charset="utf-8">

列出几个比较常用的:

  • 设置网页编码
<meta http-equiv=Content-Type content="text/html;charset=utf-8">
  • 设置缓存时间
<meta http-equiv="Cache-Control" content="max-age=604800">
  • 声明视窗大小、禁止用户缩放、移动端必备
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
  • 设置兼容IE,百度用的就是这种方式
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  • 申明网站为PC站,避免被转码
<meta name="applicable-device" content="pc">
  • 禁止浏览器转码
<meta http-equiv="Cache-Control" content="no-transform">
  • 规定360使用webkit内核渲染
<meta name="renderer" content="webkit">

此外还有更多关于SEO优化的,就不细讲了。

meta标签更多详细内容见:https://blog.csdn.net/yc123h/article/details/51356143

15.H5新增标签与废弃标签,H5新特性、CSS3新增属性与废弃属性。

H5新增:

  • 语义和结构元素:header、nav、article、section、footer、aside、
  • 多媒体元素:audio、vedio、source、embed、等
  • 表单元素:datalist、output、keygen(废弃)等
  • 注释标签:ruby、rt、rp
  • 其他:hgroup、figure、figcaption、datalist、canvas、svg、dialog、progess、time、mark、details、summary、bdi、track、main、template、menu、menuitem、code

 H5废弃:<.acronym>、<applet>、<basefont>、<big>、<center>、<dir>、<font>、<frame>、<frameset>、<isindex>、<noframes>、<s>、<strike>、<tt>、<u>、<xmp>

H5新特性:绘图(Canvas和SVG)、多媒体、地理定位、离线&存储、通信(Server-Sent-Event/Websocket)、其他(WebWorkers、XMLHttpRequest2、HistoryAPI、拖放API、requestAnimationFrame、全屏API、指针锁定API、在线和离线事件、文件API)

另附上:XMLHttpRequest2介绍

16.IE兼容的方法。

  • IE注释
使IE5,IE6,IE7,IE8兼容到IE9模式
<!–[if lt IE 9]>
<script src=”http://ie7-js.googlecode.com/svn/version/2.1(beta4)/IE9.js”></script>
<![endif]–>
  • meta标签(推荐,百度、淘宝标配)
<meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1">

17.伪类和伪元素的区别

区别:伪类的名字更像是一种状态,比如active,伪元素的名字更像是元素,比如first-letter

(一般建议伪类用单冒号,伪元素双冒号,不过因为兼容性的问题,所以现在大部分还是统一的单冒号)

伪类                                               :Pseudo-class

伪元素             :Pseudo-elements

18.a标签伪类的排列顺序

排列顺序为:link,:visited,:hover,:active,简单记法就是LoVe&&HAte  (爱&恨)

19.说下html5 <template>

官网介绍为The template element is used to declare fragments of HTML that can be cloned and inserted in the document by script.

<template> 元素 是一种用于保存客户端内容的机制,该内容在页面加载时不被渲染,但可以在运行时使用JavaScript进行实例化。

可以将一个模板视为正在被存储以供随后在文档中使用的一个内容片段。

虽然, 在加载页面的同时,解析器确实处理 <template>元素的内容,这样做只是确保这些内容是有效的; 然而,元素的内容不会被渲染。

以前的话我们可能会使用<script type="text/template"></script>或者是使用<textarea>、<xmp>(已废除)来实现大量html代码的插入

但是那样的性能不太好,而template的性能更好,原因它使用的DocumentFragment对象来存储它的内容,一次性插入,所以快很多。

目前很多主流的框架(Vue/React/Angular)都使用了<template>。

详见:<template>|MDN

 20.CSS选择器的顺序

主要是!important>内联样式>id选择器>类选择器=伪类选择器=属性选择器>伪元素=类型选择器(元素选择器)

通配选择符(universal selector)(*), 关系选择符(combinators) (+>~, ' ')  和 否定伪类(negation pseudo-class)(:not()) 对优先级没有影响。(但是,在 :not() 内部声明的选择器是会影响优先级)。

相同优先级的话,哪个在后面,哪个就起作用(也就是覆盖)。

还是要看官网CSS优先级

21.css隐藏页面的方式

  • opacity:0;                                                       仍然占据位置,可响应交互。
  • visibility:hidden;                                        仍然占据位置,不响应交互。
  • display:none.                                                 不占据位置,不响应交互,读屏软件无法读到隐藏的文字
  • position绝对定位移出可视区域                      不占据位置,响应交互
  • clip-path裁剪区域面积为0                              不占据位置,不响应交互,读屏软件可以读到隐藏的文字

 

22.BFC和IFC?GFC? FFC?

BFC:Block Fomatting Context

还是要搬来官方文档:块级格式化上下文

IFC:Inline Fomatting Context

GFC:网格布局上下文

FFC:弹性布局上下文

具体介绍看官方文档。

23.可以继承的css属性有?

详见https://www.cnblogs.com/thislbq/p/5882105.html

 未完待续

JS

 1.js中的apply与call有什么区别?以及bind?

这两个方法都是在特定作用于中调用函数,实际上等于设置函数体内this对象的值。

区别:apply与call接受参数的方式不同,而bind需要执行,并且只需一个参数。

apply()方法接受两个参数。一个是在其中运行函数的作用域,另一个是参数数组。例如:B.apply(A,arguements)即A对象应用B对象的方法。

call方法第一个参数是this值没有变化,变化的是其余参数都直接传递给函数。例如:B.call(A,arg1,arg2)即A对象调用B对象的方法。

bind方法用于为在其他上下文中执行的函数保留执行上下文,也就是把其他函数的this传递到bind.例如B.bind(A)即把A的this传递给B。

2.js是如何实现继承的?

JS主要通过原型链实现继承。原型链的构建是通过将一个类型的实例赋值给另一个构造函数的原型实现的(SubType.prototype=new SuperType();)。这样子类型就能够访问超类型的所有属性和方法。

原型链的问题是对象实例共享所有继承的属性和方法,因此不适宜单独使用。解决这个问题的技术是借用构造函数即在子类型的构造函数的内部调用超类型的构造函数(SuperType.call(this);)。

这样就可以做到每个实例都具有自己的属性,同时还能保证只是用构造函数模式来定义类型。

使用最多的继承模式是组合继承,这种模式使用原型链继承共享的属性和方法,而通过借用构造函数继承实例属性。此外还存在下列可供选择的继承模式:原型式继承、寄生式继承、寄生组合式继承。

3.事件流?事件冒泡?事件委托?

事件流描述的是事件从页面中接收的顺序。

DOM2级规定事件流分为三个阶段:事件捕获阶段、处于目标阶段、事件冒泡阶段。

事件冒泡指的事件开始时由最具体的元素(文档节点中嵌套层次最深的那个节点)接收,然后向上逐级传播到较为不具体的节点。

事件委托用了事件冒泡,只指定一个事件处理程序就可以管理某一类型的所有事件。

4.如何阻止事件的默认行为?

在普通浏览器中是event.preventDefault();IE中则是event.returnValue=false

注:在html事件属性中或者DOM0级事件处理时可以用return false;

补充:阻止冒泡的话在普通浏览器中为event.stopPropagation(),在IE中为window.event.cancelBubble=true;

阻止冒泡行为:

function stopBubble(e) { 
    //如果提供了事件对象,则这是一个非IE浏览器 
    if ( e && e.stopPropagation ){ 
        e.stopPropagation(); //因此它支持W3C的stopPropagation()方法 
    }else{ 
        window.event.cancelBubble = true; //否则,我们需要使用IE的方式来取消事件冒泡 
    }
}

阻止默认行为:

function stopDefault( e ) { 
    if ( e && e.preventDefault ){
        e.preventDefault(); //阻止默认浏览器动作(W3C) 
    }else {
        window.event.returnValue = false; //IE中阻止函数器默认动作的方式 
    }
    return false; 
}

5.谈下new做了什么。

在用new操作符调用构造函数时会经历以下步骤。

(1) 创建一个新对象;
(2) 将构造函数的作用域赋给新对象(因此 this 就指向了这个新对象) ;
(3) 执行构造函数中的代码(为这个新对象添加属性) ;
(4) 返回新对象

//实现一个new方法
function New() {
    let obj = new Object(), 
        Constructor = [].shift.call(arguments);
    obj.__proto__ = Constructor.prototype;
    let ret = Constructor.apply(obj, arguments);
    return typeof ret === 'object' ? ret : obj;
};

6.箭头函数的特点:

1)没有 this 、 super 、 arguments ,也没有 new.target 绑定: this 、 super 、
arguments 、以及函数内部的 new.target 的值由所在的、最靠近的非箭头函数来决定
( super 详见第四章)。
2)不能被使用 new 调用: 箭头函数没有 [[Construct]] 方法,因此不能被用为构造函
数,使用 new 调用箭头函数会抛出错误。
3)没有原型: 既然不能对箭头函数使用 new ,那么它也不需要原型,也就是没有
prototype 属性。
4)不能更改 this : this 的值在函数内部不能被修改,在函数的整个生命周期内其值会
保持不变。
5)没有 arguments 对象: 既然箭头函数没有 arguments 绑定,你必须依赖于具名参数或
剩余参数来访问函数的参数。
6)不允许重复的具名参数: 箭头函数不允许拥有重复的具名参数,

7.var a=[]与var a=new Array()的区别?

因为 JSON格式的语法是引擎直接解释的。而new Array 则需要调用Array的构造器。还有就是

  • 1.当你需要将一个数字转化为字符串时可以这样定义:var s=""+1; 这样的转化最快。
  • 2.当你定义一个对象类型时:var o={}; 而已 var o=new Object();道理是同样,new Object()需要调用Object的构造器。
  • 3.在js中执行字符串替换时,或查找字符串,需要进行循环时,可以考虑使用正则,速度更快。
  • 4.尽可能的少定义、使用全局变量

8.跨域以及解决办法。

跨域有两种:一种是跨域源资源共享(CORS),一种是跨文档消息传递(XDM)。一般来说是CORS。所以要问清楚题目意思,这也是为什么很多问题答案不一样。

根据MDN Web Docs 里的定义,跨域是指当一个资源从与该资源本身所在的服务器不同的域或端口不同的域或不同的端口请求一个资源时,资源会发起一个跨域 HTTP 请求也就是说,正常的跨域情况,是你访问了一个A网站,然后这个网站返回的资源里面,请求了B网站/端口的资源,于是就跨域了。
 
出于安全原因,浏览器限制从脚本内发起的跨源HTTP请求。 例如,XMLHttpRequest和Fetch API遵循同源策略。 这意味着使用这些API的Web应用程序只能从加载应用程序的同一个域请求HTTP资源,除非使用CORS头文件。
(跨域并不一定是浏览器限制了发起跨域请求,可能是跨域请求可以正常发起,但是返回结果被浏览器拦截了,因为返回结果的没有CORS头部信息,或者不匹配)
注意:跨域请求不包含cookie信息,因此普通ajax请求不包含cookie
 
 
实现跨域源资源共享
  • 设置允许CORS的头部(需要服务器配合)
  • 图像Ping(只能GET请求,无法访问响应文本)
  • JSONP技术(支持双向通信,只能GET请求,不安全,访问的域容易参杂恶意代码,判断请求是否失败不容易)
  • 使用代理服务器
(图像Ping和JSONP都是利用了script标签和img标签的src属性可以跨域请求资源)
注:IE使用XDR(XDomainRequest)来实现跨域通信.,其他浏览器使用XHR对象,浏览器已经通过XHR对象实现了对CORS的原生支持,在尝试打开不同来源的资源时,请求会自动添加CORS头部。
 
实现跨文档消息传递
  • 通过修改document.domain来跨子域(适用于一级域名相同,二级域名不同)
  • 使用window.name来进行跨域
  • 使用HTML5中新引进的window.postMessage方法来跨域传送数据(推荐)
  • 修改url使用片段标识符来通信

9.了解哪些设计模式?

详见JS常见设计模式总结

10.["1", "2", "3"].map(parseInt) 的结果为

[1,NaN,NaN]

具体分析可见:http://www.cnblogs.com/wuguanglin/p/mapAndParseInt.html

11.函数节流和函数防抖

节流:如果你持续触发事件,每隔一段时间,只执行一次事件。

防抖:你尽管触发事件,但是我一定在事件触发 n 秒后才执行,如果你在一个事件触发的 n 秒内又触发了这个事件,那我就以新的事件的时间为准,n 秒后才执行,总之,就是要等你触发完事件 n 秒内不再触发事件,我才执行,真是任性呐!

详细代码见:

https://github.com/mqyqingfeng/Blog/issues/22

https://github.com/mqyqingfeng/Blog/issues/26

数据结构与算法

1.数组、链表、Hash(散列表)的优缺点。

数组优点:定义简单、查询快速。缺点:删除麻烦。

链表优点:查询慢。 缺点:定义麻烦、删除容易

Hash综合了数组和链表的优点:既查询快速,也删除容易。

缺点是不能存放重复的属性。

2.常用排序算法及其区别。

七大排序算法总结

3.常用搜索算法及其区别。

未完待续。

计算机网络

1.http、https协议。

http:http://www.runoob.com/http/http-tutorial.html

https协议详解:https://www.cnblogs.com/zxj015/p/6530766.html

这篇文章讲的很全,除了http还有https,websocket,http/2,以及各种网络攻击。

2.get与post的区别

  1. GET提交的数据会放在URL之后,以?分割URL和传输数据,参数之间以&相连,如EditPosts.aspx?name=test1&id=123456. POST方法是把提交的数据放在HTTP包的Body中.
  2. GET提交的数据大小有限制(因为浏览器对URL的长度有限制),而POST方法提交的数据没有限制.
  3. GET方式需要使用Request.QueryString来取得变量的值,而POST方式通过Request.Form来获取变量的值。
  4. GET方式提交数据,会带来安全问题,比如一个登录页面,通过GET方式提交数据时,用户名和密码将出现在URL上,如果页面可以被缓存或者其他人可以访问这台机器,就可以从历史记录获得该用户的账号和密码.

3.http协议的不同版本

这个想要看最规范的就可以去看RFC规范,但是我们一般都建议看MDN

http/0.9

  只有一个Get命令

http/1.0

  1.能传输图像、视频、二进制文件

  2.增加了POST、HEAD命令

  3.除了数据部分,每次通信都必须包括头信息(HTTP header),用来描述一些元数据。

  4.其他的新增功能还包括状态码(status code)、多字符集支持、多部分发送(multi-part type)、权限(authorization)、缓存(cache)、内容编码(content encoding)等。

  缺点:每个TCP连接只能发送一个请求。发送数据完毕,连接就关闭,如果还要请求其他资源,就必须再新建一个连接。

http/1.1

  1.持久连接

  2.管道机制

  3.分块传输编码

  4.增加了PUT、CONNECT、OPTIONS、DELETE、TRACE方法

  5.头信息增加了Host字段

  缺点:同一个TCP连接,数据通信是按次序进行的,容易造成“队头堵塞”。

    为了避免这个问题,只有两种方法:一是减少请求数,二是同时多开持久连接

http/2

  1.彻底的二进制协议。(头信息和数据体都是二进制,并且统称为"帧"(frame):头信息帧和数据帧。)

  2.多工(双向的、实时的通信)

  3.数据流

      HTTP/2 将每个请求或回应的所有数据包,称为一个数据流(stream)。HTTP/2 可以取消某一次请求,同时保证TCP连接还打开着,

      可以被其他请求使用。客户端还可以指定数据流的优先级。优先级越高,服务器就会越早回应。

  4.头信息压缩

      一方面,头信息使用gzipcompress压缩后再发送;另一方面,客户端和服务器同时维护一张头信息表,

      所有字段都会存入这个表,生成一个索引号,以后就不发送同样字段了,只发送索引号,这样就提高速度了。

  5.服务器推送

详情见阮一峰的HTTP协议入门

4.TCP与UDP的区别。

  1. TCP面向连接的,UDP是无连接的 
  2. 对系统资源的要求。(TCP多,UDP少)
  3. UDP程序结构简单。
  4. TCP保证数据正确性,UDP可能丢包。
  5. TCP保证数据顺序,UDP不保证。
  6. TCP提供可靠的服务,而UDP尽最大努力交付,也就是不可靠交付。
  7. UDP吞吐量不受拥挤控制算法的调节,只受应用软件生成数据的速率、传输带宽、源端和终端主机性能的限制
  8. UDP可以实现广播和多播。

参考自:https://www.cnblogs.com/longiang7510/p/5441502.html

5.WEB安全(XSS、CSRF/XSRF、开放重定向、SQL注入、点击劫持/UI覆盖攻击、Dos攻击)

详见http://www.cnblogs.com/Erik_Xu/tag/Web%E5%AE%89%E5%85%A8/

以及另一篇:https://blog.csdn.net/vivian_jay/article/details/58667283

框架

1.Vue的生命周期。

vue生命周期

vue的生命周期分为8个阶段:beforeCreate(创建前)、created(创建后)、beforeMount(被载入前)、Mounted(载入后)、beforeUpdate(更新前)、updated(更新后)、beforeDestroyed(销毁前)、destroyed(销毁后)。

另外vue生命周期主要就是要知道父子组件的生命周期顺序,而这个顺序跟vue源码有很大的关系。

2.vue虚拟DOM 

DOM是文档对象模型(Document Object Model)的简写,在浏览器中我们可以通过js来操作DOM,但是这样的操作性能很差,于是Virtual Dom应运而生。Virtual Dom就是在js中模拟DOM对象树来优化DOM操作的一种技术或思路。

当根据vdom来操作dom时候,vdom会使用diff算法得到最优的方法去操作dom。diff算法内容比较多,其实主要就是比较vnode和oldNode,就不介绍了。

详见:https://segmentfault.com/a/1190000008291645

或者:https://segmentfault.com/a/1190000008782928

3.vue兄弟组件通信。

两种方式:

1).主要是通过Event Bus

var bus = new Vue();

bus.$emit()
bus.$on()

2).当然也可以通过父组件做中介者。

子组件emit父组件事件,父组件数据改变,通过props传递给另一个子组件。

4.vue双向绑定的原理

这里推荐下Github上最火的vue源码讲解:https://github.com/answershuto/learnVue

Vue.js的响应式原理依赖于Object.defineProperty,尤大大在Vue.js文档中就已经提到过,这也是Vue.js不支持IE8 以及更低版本浏览器的原因。Vue通过设定对象属性的 setter/getter 方法来监听数据的变化,通过getter进行依赖收集,而每个setter方法就是一个观察者,在数据变更的时候通知订阅者更新视图。从而实现model=>view。

通过addEventListener来监听对应的事件,则可以实现从视图到数据

5.如何优化vue效率

  • 正确使用v-if与v-show
  • v-for循环使用组件时使用key
  • 使用vue组件的keep-alive做缓存
  • 减少代码,将重复的代码封装成方法、组件。对于全局使用的组件通过Vue.use()去使用
  • 在vue组件里的style标签里写样式
  • 将vue、vuex、vue-router单独拿出来打包
  • 引入第三方组件库时按需加载
  • 每个组件的方法最好按照顺序来写,如 data、props、钩子、watch、computed、components。
  • 父子组件传值时尽量只传需要的参数
  • 合理使用computed、method、watch
  • 组件懒加载

未完待续。。。。。

原文地址:https://www.cnblogs.com/wuguanglin/p/interview.html