前端面试题

+@[TOC]

网络请求------------------------------------------------------------------------------------------------------

1、get、post的区别

此题比较简单,但一定要回答的全面

1.get 参数通过 url 传递,post 放在  body 体中。(get把请求的数据在URL后通过?连接,通过&进行参数分割。psot将参数存放在HTTP的包体内)

2.get传递数据是通过URL进行传递,对传递的数据长度是受到URL大小的限制,URL最大长度是2048个字符。post没有长度限制
3.get后退不会有影响,post后退会重新进行提交

4.get请求可以被缓存,post不可以被缓存

5.get请求只URL编码,post支持多种编码方式

6.get请求的记录会留在历史记录中,post请求不会留在历史记录

7.get只支持ASCII字符,post没有字符类型限制

8、get不安全,因为参数直接暴露在 url 中,所以不能用来传递敏感信息。

2、你所知道的http的响应码及含义?

此题有过开发经验的都知道几个,但还是那句话,一定要回答的详细且全面。

1xx(临时响应)

100: 请求者应当继续提出请求。

101(切换协议) 请求者已要求服务器切换协议,服务器已确认并准备进行切换。

2xx(成功)

200:正确的请求返回正确的结果

201:表示资源被正确的创建。比如说,我们 POST 用户名、密码正确创建了一个用户就可以返回 201。

202:请求是正确的,但是结果正在处理中,这时候客户端可以通过轮询等机制继续请求。

3xx(已重定向)

300:请求成功,但结果有多种选择。

301:请求成功,但是资源被永久转移。

303:使用 GET 来访问新的地址来获取资源。

304:请求的资源并没有被修改过

4xx(请求错误)

400:请求出现错误,比如请求头不对等。

401:没有提供认证信息。请求的时候没有带上 Token 等。

402:为以后需要所保留的状态码。

403:请求的资源不允许访问。就是说没有权限。

404:请求的内容不存在。

5xx(服务器错误)

500:服务器错误。

501:请求还没有被实现。


3http和https

是超文本传输协议,信息是明文传输;https 是基于 ssl 加密的 http 协议,比 http 协议安全。使用不同的链接方式,端口也不同,一般而言,http 协议的端口为 80,https 的端口为443。Https 协议需要 ca 证书,费用较高。

4. http 请求方式有哪些?

HTTP1.0 定义了三种请求方法: GET, POST 和 HEAD 方法。 HTTP1.1 新增了五种请求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法

5.什么情况造成跨域?

同源策略限制 不同源会造成跨域。以下任意一种情况不同,都是不同源。

同源:协议 域名 端口号全部相同 只要有一个不相同就是非同源策略

6.跨域解决方案有哪些?

原理:动态创建一个script标签。script 叫做作用域属性。利用script标签的src属性不受同源策略限制。因为所有的src属性和href属性都不受同源策略限制。可以请求第三方服务器数据内容。

开发环境的跨域配置proxyTable 在config文件夹中的index.js中设置proxyTable

7.三次握手

TCP协议是一种面向连接的、可靠的、基于字节流的传输层通信协议,采用全双工通信。

那为什么需要三次握手呢?请看如下的过程:

A向B发起建立连接请求:A——>B;
B收到A的发送信号,并且向A发送确认信息:B——>A;
A收到B的确认信号,并向B发送确认信号:A——>B。
四次挥手

那为什么需要四次挥手呢?请看如下过程:

A向B发起请求,表示A没有数据要发送了:A——>B;
B向A发送信号,确认A的断开请求:B——>A;
B向A发送信号,请求断开连接,表示B没有数据要发送了:B——>A;
A向B发送确认信号,同意断开:A——>B。
可能有朋友会问,为什么2、3次挥手不能合在一次挥手中?那是因为此时A虽然不再发送数据了,但是还可以接收数据,B可能还有数据要发送给A,所以两次挥手不能合并为一次。
挥手次数比握手多一次,是因为握手过程,通信只需要处理连接。而挥手过程,通信需要处理数据+连接。

Ok,TCP连接就这样关闭了!

8.  描述一下 cookies/sessionStorage 和localStorage 的区别?

cookies 是网站为了表示用户身份而储存在用户本地终端上的数据, Cookies 的数据始终在同源的 http 请求中携带,会在浏览器和服务器中来回传递,大小不能 4K(通常经过加密,所以不用担心账号被盗, 同源策略[同源是指"协议+域名+端口" 三者相同] 可以防止 XSS 和 CSRF 攻击浏览器,XSS 就是用过浏览 器的 cookies,截取用户数据,CSRF 是模拟用户在网页上面的操作,完成数据请求、异步策略牵扯到了 JSONP) sessionStorage 和 localStorage 的数据都是在本地存储,不会把数据发给服务器,localStorage 是关闭 浏览器,数据还存在不会丢失,而 sessionStorage 是离开浏览器后,数据会自动删除.localStorage 和 sessionStory 两种本地离线缓存

9. 如何实现浏览器内多个标签之间的通信?

Websocket/SharedWorker  都是可以将不同线程共享为一个线程,他们的数据也是共享的。 LocalStorage 也可以实现浏览器多个标签页之间的通信。 localStorage 在另一个浏览器被添加/删除/修改时,会触发一个事件, 我们可以通过对 loacalStorage 监听事件,控制他的值来进行信息通信。

10. 在地址栏里输入一个 URL,到这个页面呈现出来,中间会发生什么?

  • DNS解析
  • TCP连接
  • 发送HTTP请求
  • 服务器处理HTTP请求并返回报文
  • 浏览器解析渲染页面
  • 连接结束

    

#CSS-----------------------------------------------------------------------------

11、对盒模型的理解

标准盒子模型、IE盒子模型

  • 标准盒模型的width和height属性的范围只包含了content,
  • IE盒模型的width和height属性的范围包含了border、padding和content。
  • 可以通过修改元素的box-sizing属性来改变元素的盒模型:

  • box-sizing: content-box表示标准盒模型(默认值)

  • box-sizing: border-box表示IE盒模型(怪异盒模型)

12、什么是CSS reset?

reset.css ====》 重置css样式的   

非要说他问题:体积大了一点点点

normalize.css  是现在用的比较多的,但是和reset有区别。

  是干什么:为了增强跨浏览器渲染的一致性(一定程度上),维护的一个CSS 重置样式库。

13、CSS3新特性

CSS3实现圆角边框(border-radius),阴影(box-shadow),

rem是CSS3新增的一个相对单位

对文字加特效(text-shadow、),线性渐变(gradient),旋转(transform)

transform:rotate(9deg) scale(0.85,0.90) translate(0px,-30px) skew(-9deg,0deg);// 旋转,缩放,定位,倾斜

增加了更多的CSS选择器 多背景 rgba

在CSS3中唯一引入的伪类是 ::selection.

媒体查询,多栏布局

border-image

14、css sprite是什么,有什么优缺点

雪碧图 === 精灵图

1. 是什么 : 把一堆小图标放在一张大图片上。

2. 优点:减少了http请求,做了性能上的优化。

3. 缺点:维护性,修改性,较差。

15、position有哪些值?有什么作用? 【特别多公司问】

static [默认]    没有定位

fixed           相对于浏览器窗口

absolute  相对于第一个拥有relative的父元素的

relative  相对于自身

16、absolute和relative区别

1. relative不脱离文档流,absolute脱离文档流

2. relative只有俩个值(left、right、top、bottom如果同时存在left干掉right,top干掉bottom)

     absolute可以写四个值

17、line-height和height有什么区别?

height          : 是高度

line-height : 是行高

height就是盒子的高度,line-height是每一行文字的高度(高度值会随着内容发生改变的)。【重点】

18.自适应:

引入flexible.js文件。单位使用rem

19.清除浮动的方式

父盒子不设置高度,子盒子设置高度时,父盒子的高度取决于子盒子的高度, 如果子盒子浮动了, 子盒子就会脱离标准流,俗称脱标,就会导致父盒子高度变为0,这个时候,就需要清除浮动带来的影响,让父盒子重新获得高度, 称为清除浮动.

第一种方法:  直接给父盒子加高度(不推荐)(为什么不推荐呢?因为在开发中,很多时候,我们外面的盒子是无法确认高度的,需要有内容将高度撑起来,这种方式显然就不太适合,所以不推荐.)

第二种方法:给父元素添加 overflow:hidden 优点:代码较少,简单方便 缺点:不能配合定位使用

第三种方法:在子元素并级后面添加一个新元素,添加 clear:both 属性 优点:通俗易懂,容易掌握 缺点:添加无意义空标签,不方便后期维护

第四种 : :after 方法(作用于浮动元素的父元素) 优点:结构和语义化完全正确 缺点:复用方式不当,会造成代码量增加

 .clearfix:after{/*伪元素是行内元素 正常浏览器清除浮动方法*/
        content: "";
        display: block;
        height: 0;
        clear:both;
        visibility: hidden;  }
    .clearfix{
        *zoom: 1;/*ie6清除浮动的方式 *号只有IE6-IE7执行,其他浏览器不执行*/  }

20、Display 有哪些哪些值?说明他们的作用

block 元素转化为块级元素 inline 元素转化为行内元素 inline_block 元素转化问行内块元素 None 次元素不会显示,脱离文档流 List-item 元素转化为行内样式,并添加列表样式(如UL 下的li) Table 元素会以块级表格来显示

21.  /scss

可以使用变量($变量名=值);变量 、嵌套、Mixin混合、function函数、插值

Class中嵌套class,从而减少重复的代码

less是一种动态样式语言. 对CSS赋予了动态语言的特性,如变量、继承、运算、函数。

22、CSS 打造三角形?

宽度 0,高度 0,边框加宽,给一边加颜色,其余三边使用 transparent

23. Label 的作用是什么?怎么用?
label 标签是定义表单控制间的关系,当用户点击 label 里面的文字时,浏览器会自动把光标转载表单控件上    

24、 满屏品字布局?
上面 div 宽度 100%; 下面两个宽度 width50%+float/display:inline/inlin-block

25 li 与 li 之间有看不见的空白间隙是什么原因引起来的?

行内块排列会受到(空格/回车)等的影响,因为空格也属于字符,把字符大小 设置为 0 就 ok 了

.wrap ul{font-size:0px;}

26 为什么要初始化css 样式?

浏览器的兼容性问题,有些浏览器对标签的默认值是不一样的,如果没有设置 CSS 初始化,浏览器之间 的页面会有差异,简单的方式:

*{   padding: 0; margin: 0; }

27 、响应式页面?

响应式页面主要为了配合各种用户设备的窗口宽度,主要用得到的一个是媒体查询,一个是 bootstrap,一个 是 rem 单位,rem 根据页面字体大小等比缩放, 可以用 vw/vh+rem,vw/vh 是将窗口大小评分为 100 份;

28、  CSS 如何实现横向滚动与竖向滚动?

横向滚动:父元素 overflow-x:auto;    overflow-y:hidden; 竖向滚动:父元素 overflow-x:hidden;overflow-y:auto;

29、 如何设置滚动条样式?

Scrollbar 样式属性,有很多种,很少用,单词没怎么记住;

30.  行内元素/块级元素/空元素有哪些?

行内元素:a/img/span/b/strong/input/buttonj/select/section                                                                       块级元素:div/p/table/ul/ol/li/h1-h6

31.设置元素浮动后,元素的 display 值是什么吗?

浮动后,元素的 display 值自动变为 display:block;

32、有一个高度自适应的div,里面有两个 div,一个高度 100px,一个如何自适应高度?

前端面试题_第1张图片

宽高自适应,高度恒为宽度的70% (padding-top:50% ,则高度恒为宽度的一半):

width:100% ;
height:0;
padding-top:70%

33.有什么不同的方式可以隐藏内容?

visibilty:hidden:元素任然在文档流中,并占用空间; display:none:元素脱离文档流,不占用空间; position:left:-999999px:将内容至于屏幕之外 text-index:-9999:只适用于 block 元素中的文本

display:none与visibilty:hidden:  隐藏元素   

区别:1、display:none:元素脱离文档流,不占用空间;visibilty:hidden:元素任然在文档流中,并占用空间;(原理:display:none 第一次不绘制,visibility:hidden进行第一次绘制)

2、display:none重绘回流   。visibilty:hidden 重绘(触发回流必定会触发重绘,触发重绘不一定会触发回流)

34、回流重绘

元素的规模尺寸、布局、隐藏等改变而需要重新构建;这就被称为回流。

元素需要更新的属性只是影响元素的外观、风格,而不影响布局的,为重绘。回流必将引起重绘,但是重绘不一定会引起回流(回流比重绘的代价要更高,回流的花销跟render tree有多少节点需要重新构建有关系)


35、  CSS 实现单行文本移除显示...

overflow : hidden ;                                                                                                                        text-overflow : (值为 clip 是修剪文本;ellipsis 为显示省略符号);                                       white-space : nowrap
string 为使用给定的字符串来代表被修剪的文本。 ;   还需要加宽度 width 属性来兼容部分浏览器

实现多行文本溢出显示...display : -wedkit-box ; -webkit-box-orient : vertical ; -webkit-line-clamp : 3 ; overflow : hidden  

适用范围 :  因使用了Webkit 的CSS 扩展属性,该方法适用于Webkit 浏览器以及移动端 注:

-webkit-line-clamp 用来限制在一个块元素显示的文本的行数,为了实现该效果,它需要组合其它的 webkit 属性。
常见结合属性:

display:-webkit-box; 必须结合的属性,将对象作为弹性伸缩盒子模式显示。 -webkit-box-orient 必须结合的属性,设置或减缩伸缩盒对象的子元素排列方式。

36. em,rem,px 的区别?

  • px是固定的像素,一旦设置了就无法因为适应页面大小而改变。
  • em和rem相对于px更具有灵活性,他们是相对长度单位,其长度不是固定的
  • ,更适用于响应式布局。
  • em是相对于其父元素来设置字体大小,这样就会存在一个问题,进行任何元素设置,都有可能需要知道他父元素的大小。而rem是相对于根元素,这样就意味着,只需要在根元素确定一个参考值。
  • 使用场景:

  • 对于只需要适配少部分移动设备,且分辨率对页面影响不大的,使用px即可 。
  • 对于需要适配各种移动设备,使用rem,例如需要适配iPhone和iPad等分辨率差别比较挺大的设备。
  • vw/vh 和百分比很类似,两者的区别:

  • 百分比(%):当浏览器的宽度或者高度发生变化时,通过百分比单位可以使得浏览器中的组件的宽和高随着浏览器的变化而变化,从而实现响应式的效果。一般认为子元素的百分比相对于直接父元素。一般认为子元素的百分比相对于直接父元素。
  • vw/vm:相对于视窗的尺寸

37、居中

水平居中:行内元素: text-align: center----------块级元素: margin: 0 auto(必须有宽度)

垂直居中: 行内元素:设置line-height 等于height
块级元素:1、 position:absolute +top:50%+ transform:translateY(-50%)
                  2、display: flex + align-items: center+justify-content: center;
                  3、display: table+display:table-cell + vertical-align: middle

                  4、关键语句:父元素display: flex;(弹性盒子)子元素margin: auto;(上下左右居中)

元素水平垂直居中

方案1:position 元素已知宽度
父元素设置为:position: relative;
子元素设置为:position: absolute;
距上50%,据左50%,然后减去元素自身宽度的距离就可以实现(绝对定位+transform实现垂直水平居中,可以不知道子元素高宽度:position:absolute;top:50%;left:50%;transform:translate(-50%,-50%))

方案2:flex布局

display: flex;//flex布局

justify-content: center;//使子项目水平居中

align-items: center;//使子项目垂直居中

方案3:元素有宽度和高度时,利用margin:auto设置元素水平垂直居中:

3、使用display为table,子元素为display:table-cell;vertical-align:center;text-align:center子子元素设置为vertical-align:center

子元素设置为margin:auto;position:absolute;top:0;left:0;right:0;bottom:0

图片居中对齐(图片和旁边的文字垂直居中对齐):vertical-align:middle

38 link 标签和 import 标签的区别

link 属于 html 标签,而@import 是 css 提供的
页面被加载时,link 会同时被加载,而@import 引用的 css 会等到页面加载结束后加载。
link 是 html 标签,因此没有兼容性,而@import 只有 IE5 以上才能识别。
link 方式样式的权重高于@import 的

39.  如何在页面上实现一个圆形的可点击区域?

Border-radius

40.css选择器

id 选择器,class 选择器,标签选择器,伪元素选择器,伪类选择器等

内联选择器:将CSS样式写在元素的style属性当中

类别选择器:类别选择器是通过class属性去选中元素

!important>内联选择器>ID选择器>类别选择器>属性选择器>伪类>元素选择器>通配符选择器>继承选择器 

样式表的来源不同时,优先级顺序为:内联样式> 内部样式 > 外部样式 > 浏览器用户
自定义样式 > 浏览器默认样式

41.伪类与伪元素

伪元素和伪类的区别和作用?

伪元素:在内容元素的前后插入额外的元素或样式,但是这些元素实际上并不在文档中生成。它们只在外部显示可见,但不会在文档的源代码中找到它们,因此,称为“伪”元素。例如:

p::before {content:"第一章:";} 
p::after {content:"Hot!";} 
p::first-line {background:red;} 
p::first-letter {font-size:30px;}

伪类:将特殊的效果添加到特定选择器上。它是已有元素上添加类别的,不会产生新的元素,如:

a:hover {color: #FF00FF}
p:first-child {color: red}

总结:伪类是通过在元素选择器上加⼊伪类改变元素状态,⽽伪元素通过对元素的操作进⾏对元素的改变。

42、CSS3 中对溢出的处理

text-overflow 属性,值为 clip 是修剪文本;ellipsis 为显示省略符号来表被修剪的文本;
string 为使用给定的字符串来代表被修剪的文本。。要实现溢出时产生省略号的效果还须定义另外两个属性:强制文本在一行内显示(white-space:nowrap)及溢出内容为隐藏(overflow:hidden)

43.calc 属性

Calc 用户动态计算长度值,任何长度值都可以使用 calc()函数计算,需要注意的是,运
算符前后都需要保留一个空格,例如:width: calc(100% - 10px);

44. BFC-块级格式化上下文。

是一个独立的布局环境,其中的元素布局是不受外界的影响,并且在一个BFC中,块盒与行盒(行盒由一行中所有的内联元素所组成)都会垂直的沿着其父元素的边框排列。

只要元素满足下面任一条件即可触发 BFC 特性:

body 根元素

浮动元素:float 除 none 以外的值

绝对定位元素:position (absolute、fixed)

display 为 inline-block、table-cells、flex

overflow 除了 visible 以外的值 (hidden、auto、scroll)

 BFC 特性及应用

 1. 同一个 BFC 下外边距会发生折叠(如果想要避免外边距的重叠,可以将其放在不同的 BFC 容器中。)

2. BFC 可以包含浮动的元素(清除浮动)前端面试题_第2张图片

3. BFC 可以阻止元素被浮动元素覆盖

flex-grow重点说明落在 剩余 这两个字上,父元素剩余的空间,那什么算父元素剩余空间呢,简单的理解就是(父元素的宽度-子元素总和的宽度),

HTML-------------------------------------------------------------------
45 link 和$import

是一个标签 、 @import是css的内容。加载页面时,link标签引入的 CSS 被同时加载;@import引入的 CSS 将在页面加载完毕后被加载。

46、title标签和h1标签区别:

    1. title是网页标题,h1是内容。

    2. 在做网站seo的层面上   title >  h1  【重点】

47、b与strong的区别:

    1. 语义化

    2. b只是一个加粗的标签,没什么特殊含义。

       strong也是一个加粗标签,但是有特殊含义(强调:阅读器、seo)。

i与em的区别:

    1. 语义化

  2. 都是倾斜,i没有特殊含义,em有特殊含义。i一般现在都来做图标了。

48、title和alt区别 

title::鼠标移入显示的问题

alt   :图片没有加载显示的文字

在做seo,alt属性是可以解决蜘蛛抓取不到图片的问题的。

​ 49、 面试题:png、jpg、gif 这些图片格式解释一下,分别什么时候用?

jpg、jpeg  :  适合大图片(banner) , 同样的相对于png体积小一点。【失桢】       

png        :  适合小图标(图标), 同样的图片体积大。              【不怎么失桢】

gif        :  动图

50、.  HTML5 新特性有哪些?如何处理 HTML5 新标签的兼容性问题?

HTML5 新特性: 绘图方面:加入了 canvas 绘图

媒体方面: 加入了 video 和 audio 标签

语义化标签:  比如 header、nav、footer、section 、article

本地离线存储:  localStorage 和 sessionStory 两种本地离线缓存
localStorage 是长期储存数据,关闭浏览器后数据不会丢失 sessionStorage 是关闭浏览器后数据自动删除
表单控件: calendar、date、time、email、url、search ; 以及一些新技术: webwoker / websocket (säkit)/ GelolCation(ˌjēōlōˈ kāSHən)

51. Canvas 和 Svg 有什么区别?

H5的新特性。canvas 输出的是一副画布,放大会失真或者锯齿。适合比较小型的动态绘制。我们项目有个连线题是使用的canvas做的,根据选项与答案的坐标,在中间进行连线。。

svg 输出的图形是矢量图形,后期可以修改参数来自由放大缩小,不会失真和锯齿。我们项目有个字帖模块就是用这个做的。百度地图就是用svg做的。

 52.  图片懒加载理解:  

由于商城图片过多时,就会给图片加一个懒加载的缓冲效果。当图片进入可视化区域的时候才会加载, 否则图片只是一个空标签。这样可以优化页面渲染速度,提升用户体验。先将img标签中的src链接设置为空,将真正的图片链接放在自定义属性(data-src),当js监听到图片元素进入到可视窗口的时候,将自定义属性中的地址存储到src中,达到懒加载的效果。

JS----------------------------------------------------------------------------------------------------

53. 闭包

:闭包。一个函数能够访问另一个函数内部作用域的变量。外部函数执行完毕之后他的活动对象会被销毁,但是由于内部函数一直持有一个对外部函数变量的引用,导致他不会被垃圾清除算法所清除,会一直占用这块内存。形成闭包,所以闭包容易产生内存泄露。
垃圾清除算法。

闭包的最大用处有两个,一个是可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。

1.保护函数内的变量安全:如迭代器(执行一次函数往下取一个值)、生成器

2.函数防抖:在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。 实现的关键就在于setTimeOut这个函数,由于还需要一个变量来保存计时,考虑维护全局纯净,可以借助闭包来实现。

由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,解决方法是,在退出函数之前,将不使用的局部变量全部删除。

如何防止内存泄露。定时器计时器及时销毁。合理使用闭包

两种定时器 setTimeout只在指定时间后执行一次。setInterval以指定时间为周期循环执行

54. 防抖、节流

防抖:所谓防抖,就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。

节流:所谓节流,就是指连续触发事件但是在 n 秒中只执行一次函数。两种方式可以实现,分别是时间戳版和定时器版。

55. 原型和原型链

每一个实例对象都有一个叫做原型的私有属性----__proto__,指向它的构造函数的原型对象(prototype)。原型对象也有自己的__proto__,层层向上直到一个对象的原型对象为null。这一层层原型就是原型链。 作用:实例对象的__proto__指向构造函数的prototype,从而实现继承。

55-2.js的继承方式有哪些

三种:1、原型链继承 2.构造函数继承 3.组合继承(两种方式混合)

56、JS作用域考题

作用域说明:作用域就是一个变量可以使用的范围,主要分为全局作用域和函数作用域

Es6中新增了块级作用域(由大括号包裹,比如:if(){},for(){}等)

1、作用域链:先在内部找,内部找不到去外部找

2、变量提升【悬挂声明】

3、优先级:变量>声明函数(不看书写顺序的)>参数>提升

****注意:

1、window.xxx或者xxx(前面没有var、let、const)

2、除了函数外,其他的没有作用域(if、for、switch)

57、字面量创建对象和new创建对象有什么区别,new内部都实现了什么

字面量:

字面量创建对象更简单,方便阅读

不需要作用域解析,速度更快

new内部都实现了什么

1. 创建一个新对象

2. 构造函数的this指向于新对象

3. 执行构造函数中所有代码

4. 返回新对象

58、创建对象的几种方法

创建对象的方式(4种):new Object、字面量、构造函数、原型。

new 操作符 + Object 创建对象

字面式创建对象

工厂模式

构造函数模式

原型模式

混合模式(构造函数模式+原型模式)

59.  如何规避 javascript 多人开发函数重名问题

尽量少使用全局变量,尽可能的使用局部变量,这样不仅会减少变量重名的几率,更会减少内存开校, 因为局部变量一般会在函数结束后自动销毁释放内存, 而全局变量会到程序结束后才会被销毁  

60、== 和 ===的区别

  1. ==是非严格意义上的相等

  2. 值相等就相等

  3. ===是严格意义上的相等,会比较两边的数据类型和值大小

  4. 值和引用地址都相等才相等

61.JS延迟加载、异步加载

延迟加载:defer

async:立即执行脚本,但不妨碍页面其他的操作(简单粗暴:谁加载快谁先执行)

62.JS单线程:

单线程 :只有一个线程,只能做一件事

先执行主线程,主线程执行完毕后,去执行消息队列/事件队列(定时器、ajax等等)里,消息队列/时间队列=>先进先出

63.简述同步和异步的区别?

由于JS是单线程,在代码执行的时候,如果代码顺序执行,当前一段代码执行需要很长一段时间,就会影响后面代码的执行,带来的后果可能就是代码执行效率低,页面卡顿,用户体验差,为了避免这个问题,就出现了异步编程,通过回调函数来存放和执行异步代码,任务也划分为两种:同步任务和异步任务。

同步任务:即主线程上的任务,按照顺序由上至下依次执行,当前一个任务执行完毕后,才能执行下一个任务。
异步任务:不进入主线程,而是进入任务队列的任务,当主线程上的任务执行完后,才会执行任务队列里的任务,异步任务又分为宏任务和微任务

宏任务:script(整体代码)、setTimeout、setInterval、setImmediate(Node.js 环境)、UI事件、I/O(Node.js)
微任务:promise中的.then和.catch,process.nextTick()

执行顺序的总结:
1.主线程上的同步任务可以看做第一个宏任务,先执行主线程上的同步任务,将异步任务放入队列,宏任务放入下一个宏任务队列,微任务放入微任务队列,当主线程任务执行完成之后,就按照先进先出的原则执行所有的微任务,微任务执行完成后,开始执行下一个宏任务队列
2.当一个宏任务执行完成,如果微任务队列有微任务,会执行完所有微任务,再执行下一个宏任务
3.promise不属于微任务,只是promise.then()和.catch()才属于微任务
4.简单记法:主线程同步任务 = promise > promise.then() > setTimeout

64、call apply bind:

改变函数内部的this指向

call、apply、bind三个方法都有两个参数

call和apply都是立即执行函数,不必调用。第一个参数都是 this 的指向对象。call第二个参数可以接收任意个参数,apply第二个参数必须是数组或者类数组

bind(不会立即执行,需要调用 bind 返回的是一个新的函数,你必须调用它才会被执行),传参和call一样

前端面试题_第3张图片

65.typeof检测基本数据类型

string number boolen null undefined symbol

typeof undefinde //undefined

typeof 'abc'  // string

typepf  123 //number

typeof true //boolen

typeof {} //object

typeof [] //object

typeof null //object

typeof console.log  //function

instanceof 用来检测引用类型     object,包含function、Array

console.log([] instanceof Array);//true
console.log({} instanceof Object);//true

Object.prototype.toString     对象的一个原生原型扩展函数,用来精确的区分数据类型

    var type=Object.prototype.toString
    console.log(type.call(''));//object String
    console.log(type.call([]));//object Array
    console.log(type.call({}));//object Object
    console.log(type.call(false));//object Boolean
    console.log(type.call(null));//object Null
    console.log(type.call(undefined));//object Undefined
    console.log(type.call(function(){}));//object Function

66. constructor 构造器 ;指向构造他的函数

67.null和undefined区别

作者先设计出来的null后设计的undefined

1、表示无的值最好别是对象,null typeof是object

2、null可以被自动转换成0·

作者又设计了undefined,来填补之前自己设计null的坑。

null表示"没有对象",即该处不应该有值。典型用法是:

undefined表示"缺少值",就是此处应该有一个值,但是还没有定义。NAN是一个数值类型但不是一个具体的数  NAN+数值返回的都是NAN

68.深拷贝浅拷贝

基本数据类型  是按值访问  相互不会产生影响(a=b a的值变了 b的值不会变)

引用类型   是按引用传递的

浅拷贝:浅拷贝只复制某个对象的引用,而不复制对象本身,新旧对象还是共享同一块内存

Object.assign()  //是浅拷贝2、直接复制对象

前端面试题_第4张图片

深拷贝:深拷贝就是把一个对象,从内存中完整的拷贝出来,从堆内存中开辟了新区域,用来存新对象,并且修改新对象不会影响原对象

1>JSON.parse()【从一个字符串中解析出json对象】 + JSON. stringify()【从一个对象中解析出字符串】(缺点:1、如果obj里有RegExp(正则表达式的缩写)、Error对象,则序列化的结果将只得到空对象;2、如果obj里有函数,undefined,则序列化的结果会把函数或 undefined丢失;)

前端面试题_第5张图片

2>递归

③ 递归( 通用,从底层的角度 ) 基本思想 : 判断obj 是基本类型就简单赋值,对象(数组)的话 ,创建一个空[ ](obj是对象)或空{ }(obj是对象),再判断obj的属性有没有对象(数组),有递归调用递归(就是在运行的过程中不断地调用自己),没有简单赋值,直到全部赋值完毕,返回赋值后的new_obj ,

69.字符串操作方法

join:将数组中的每一个元素放进一个字符串.  例子:

arr={"I","love","you"};

str=arr.join(" ");//通过空格将数组组合成字符串 输出结果为 I love you

splite():用于把一个字符串分割成字符串数组

search():用于减缩字符串中指定的子字符串,或检索与正则表达式相匹配的字符串 indexOf():可返回某个字符换字符串中首次出现的位置

substring():用于提取字符串中介于两个指定下标之间的字符

trim():移除字符串两边的空格

replace():替换字符
 数组操作方法
length:计算数组的长度 索引:通过索引获取数组中对应值,同时也可以改变索引对应的值 indexOf:返回指定元素的位置,若元素不存在返回-1

slice:接受  1-2  个参数,参数对应的是要返回的是要返回项的起始位置和结束位置,若只有一个 参数,该方法返回从参数指定位置到数组结尾的所有项,如果还有两个参数,则返回起始位置到结 束位置项,但是不包括结束位置项,返回的结果是一个新数组。

splice:t添加删除:删除任意数量的项,只需要传入两个参数即可。要删除的第一项的位置和要删除的项数。.添加:可以向指定位置添加任意的项,只需要提供三个参数即可:起始位置,0(要删除的项数)和要添加的项。如果要添加多项可以继续在后面写参数用逗号分隔。

push:向数组末位添加若干元素,返回添加元素后数组的长度

pop:删除数组末位后一个元素,但会被删除元素

unshift:向数组头部添加若干元素,返回添加元素后的数组长度

shift:删除数组头部的第一个元素,返回被删除的元素

sort:对数组进行排序,返回排序后的数组

reverse:对数组中的数据进行反转,返回反转后的数组

concat:将两个数组合并,返回新数组(可以接受任意元素和数组,并进行拆分放 入数组)

toFixed() 方法可把 Number 四舍五入为指定小数位数的数字。

Math.random()方法返回大于等于 0 小于 1 的一个随机数。

findIndex() 查找这一组数 符合条件的第一数的下标 给他返回出来 没有返回 -1

70、遍历数组:

forEach:没有返回值  map:有返回值   filter能通过筛选条件快速给出遍历结果,不符合条件的就不会去遍历,符合条件的才会遍历,极大的节省了遍历开销成本   for of

71、for in  for  of的区别

1、推荐在循环对象属性的时候使用 for...in,在遍历数组的时候的时候使用 for...of 
2、for...in 循环出的是 key,for...of 循环出的是 value 

 72. ES6新特性

一、新增了const和let

var与let、const的区别

①var可以变量提升、var只有全局作用域和函数作用域、变量可以重复声明

②let不存在变量提升、属于块级作用域,声明的变量不能重复声明

④const 用于声明常量,必须赋值并且声明后不能再修改,无法重复声明,块级作用域。如果声明/的是复合类型数据,可以修改其属性。

二、模板字符串

我们想要将字符串和变量拼接起来,用反引号(``)将内容括起来,在反引号中,可以使用${}来写入需要引用到的变量。更方便地将字符串和变量连接起来。

三、剪头函数

箭头函数只有一个参数的时候可以省略小括号,只有一行代码的时候可以直接写在=>后面,不用写大括号return    当我们要把一个函数作为参数传入到另外一个函数里的时候用箭头函数是最多的

setTimeout(() =>{},1000)

剪头函数没有自己的this,会捕获其所在的上下文的this值,作为自己的this。(普通函数的this指向它的调用者,如果没有调用者则指向window)

箭头函数是匿名函数,不能作为构造函数,不能使用new

箭头函数没有自己的arguments对象

箭头函数没有原型属性

不需要 function 关键字来创造 省略 return 关键字

四、类和继承

class 和 extend 是一种语法糖,也是基于原型继承实现的 class 和 super calls,实例化,静态方法和构造函数

五、增强的对象字面量:
对象字面量被增强了,写法更加简洁与玲姐,同时在定义对象的时候能够做的事情更多了。
具体表现在:
可以在对象子里面量里面定义原型                                                                                                      定义方法可以不用  function  关键词                                                                                                直接调用父类方法
六、解构:es6允许按照一定的模式,从数组和对象中提取值,对变量进行赋值,这被称为解构

单层解构:

const earth = {

people: '人类',

animal: '动物'

}

const { people, animal } = earth

console.log(people, animal);//人类 动物

七、参数默认值,不定参数,拓展参数:
默认参数值:
可以在定义函数的时候指定参数的默认值,而不用像以前那样通过逻辑或操作符来达到目的了。

八、for of 值遍历:

1、for in遍历的是数组的索引(即键名),而 for of遍历的是数组元素值。

2、for in会遍历数组所有的可枚举属性,包括原型。for of遍历的只是数组内的元素,而不包括数组的原型

3、for in遍历顺序有可能不是按照实际数组的内部顺序

4、for-of循环不支持普通对象,可以通过内建的Object.keys()方法:



for (var key of Object.keys(someObject)) {
  console.log(key + ": " + someObject[key]);
}


//Object.keys:处理对象,返回可枚举的属性数组;(处理数组,返回索引值数组)
let person = {name:"张三",age:25,address:"深圳",getName:function(){}}
Object.keys(person) // ["name", "age", "address","getName"]

、Map、Set 和WeakMap、WeakSet

新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。

 Map 数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。

Set 和 Map 主要的应用场景在于 数据重组 和 数据储存。
Set 是一种叫做集合的数据结构,Map 是一种叫做字典的数据结构。
Set 本身是一种构造函数,用来生成 Set 数据结构。
Set: Set 实例的方法分为两大类:操作方法(用于数据操作)和遍历方法(用于遍历数据)

操作方法:

  • add(value)    添加数据,并返回新的 Set 结构

  • delete(value)   删除数据,返回一个布尔值,表示是否删除成功

  • has(value)    查看是否存在某个数据,返回一个布尔值

  • clear()      清除所有数据,没有返回值

let set = new Set([1, 2, 3, 4, 4]);
// 添加数据 5
let addSet = set.add(5);
console.log(addSet); // Set(5) {1, 2, 3, 4, 5}

// 删除数据 4s
let delSet = set.delete(4);
console.log(delSet); // true 此处返回值是个boolean 表示 是否删除成功

// 查看是否存在数据 4
let hasSet = set.has(4);
console.log(hasSet); // false

// 清除所有数据
set.clear();
console.log(set); // Set(0) {}

数组去重的方法
ES6 set 方法:var arr = new Set([1,2,2,3,4]);      console.log([...arr]); //(4) [1, 2, 3, 4]

遍历数组去重(indexOf方法)

实现思路:新建一个数组,遍历去要重的数组,当值不在新数组的时候(indexOf为-1)就加入该新数组中

十、Proxies
proxy 可以监听对象身上发生了什么事情,并在这些事情发生后执行一些相应的操作。一下子让我们对 一个对象有了很强的跟踪能力,同时咋数据绑定方面也很有用处。

十一、symbols
symbols 是一种基本类型,像数字、字符串还有布尔一样。表示独一无二的值。

十三、拓展运算符(...)对象中的扩展运算符(...)用于取出参数对象中的所有可遍历属性,拷贝到当前对象之中

let bar = { a: 1, b: 2 };
let baz = { ...bar }; // { a: 1, b: 2 }
  • 扩展运算符还可以将字符串转为真正的数组
[...'hello']
// [ "h", "e", "l", "l", "o" ]

十二、Promises

promise 是异步编程的一种解决方案:promise是一个对象,从它可以获取异步操作的消息;promise有三种状态: pending(等待态),fulfiled(成功态),rejected(失败态);promise是用来解决两个问题的:

  • 回调地狱,代码难以维护, 常常第一个的函数的输出是第二个函数的输入这种现象
  • promise可以支持多个并发的请求,获取并发请求中的数据
  • 这个promise可以解决异步的问题,本身不能说promise是异步的

new promise()Promise在创建的是时候 ,要求传入一个参数,这个参数本身是一个函数。我们可以传入一个剪头函数  new promise(()=>{}),这个函数本身包含两个参数new Promise((resolve,reject)=>{

})   //resolve,reject 本身它们又是函数

成功的时候用resolve

失败的时候用reject

//   setTimeout(() => {

    //       console.log('Hello World')

    //   }, 1000);

    // 参数->函数

    new Promise((resolve,reject) =>{

        setTimeout(() => {

         resolve()

      }, 1000)

    }).then(()=>{

        console.log('Hello World');

        

    })

什么情况下用promise   一般情况下有异步操作时使用promise对异步操作进行封装

前端面试题_第6张图片

new完promise之后

sync同步   async异步

operation  操作   async poeration 异步操作

前端面试题_第7张图片

Promse.all在处理多个异步处理时非常有用,比如说一个页面上需要等两个或多个ajax的数据回来以后才正常显示,在此之前只显示loading图标。(Promise.all获得的成功结果的数组里面的数据顺序和Promise.all接收到的数组顺序是一致的,即p1的结果在前,即便p1的结果获取的比p2要晚。这带来了一个绝大的好处。)在前端开发请求数据的过程中,偶尔会遇到发送多个请求并根据请求顺序获取和使用数据的场景,使用Promise.all毫无疑问可以解决这个问题。 有任何一个失败,返回失败。失败的话就返回最先失败的结果,。比如当一个页面需要在很多个模块的数据都返回回来时才正常显示,否则loading。



Promse.race就是赛跑的意思,意思就是说,Promise.race([p1, p2, p3])里面哪个结果获得的快,就返回那个结果,不管结果本身是成功状态还是失败状态。race的使用场景就是,多台服务器部署了同样的服务端代码,假如我要获取一个商品列表接口,我可以在 race 中写上所有服务器中的查询商品列表的接口地址,哪个服务器响应快,就从哪个服务器拿数据。

宏任务:setTimeout、setInterval、setImmediate、requestAnimationFrame

微任务:process.nextTick、Promise.then catch finally

前端面试题_第8张图片

我们常见的异步操作例如:

  • 添加定时器 setTimeout/setInterval
  • 执行某个动画 animate
  • 发起网络请求 request

有用过promise 吗?请写出下列代码的执行结果,并写出你的理解思路:
首先要讲一下,js 是单线程执行,那么代码的执行就有先后; 有先后,那就要有规则(排队),不然就乱套了,那么如何分先后呢?

73、JS同步任务和异步任务

单线程 :只有一个线程,只能做一件事

由于JS是单线程,在代码执行的时候,如果代码顺序执行,当前一段代码执行需要很长一段时间,就会影响后面代码的执行,带来的后果可能就是代码执行效率低,页面卡顿,用户体验差,为了避免这个问题,就出现了异步编程,通过回调函数来存放和执行异步代码,任务也划分为两种:同步任务和异步任务。

同步任务:即主线程上的任务,按照顺序由上至下依次执行,当前一个任务执行完毕后,才能执行下一个任务。
异步任务:不进入主线程,而是进入任务队列的任务,当主线程上的任务执行完后,才会执行任务队列里的任务,异步任务又分为宏任务和微任务

宏任务:script(整体代码)、setTimeout、setInterval、setImmediate(Node.js 环境)、UI事件、I/O(Node.js)
微任务:promise中的.then和.catch,process.nextTick()

执行顺序的总结:
1.主线程上的同步任务可以看做第一个宏任务,先执行主线程上的同步任务,将异步任务放入队列,宏任务放入下一个宏任务队列,微任务放入微任务队列,当主线程任务执行完成之后,就按照先进先出的原则执行所有的微任务,微任务执行完成后,开始执行下一个宏任务队列
2.当一个宏任务执行完成,如果微任务队列有微任务,会执行完所有微任务,再执行下一个宏任务
3.promise不属于微任务,只是promise.then()和.catch()才属于微任务
4.简单记法:主线程同步任务 = promise > promise.then() > setTimeout

74、 nextTick

nextTick(),是将回调函数延迟在下一次dom更新数据后调用,简单的理解是:当数据更新了,在dom中渲染后,自动执行该函数,更改数据后当你想立即使用js操作新的视图的时候需要使用它

Vue生命周期的created()钩子函数进行的DOM操作一定要放在Vue.nextTick()的回调函数中,原因是在created()钩子函数执行的时候DOM 其实并未进行任何渲染,而此时进行DOM操作无异于徒劳,所以此处一定要将DOM操作的js代码放进Vue.nextTick()的回调函数中。

场景:
1)第三方插件,在vue生成的某些dom动态发生变化时重新应用该插件。
2)视图更新之后,基于新的视图进行操作。

75、性能优化

性能是留住用户很重要的一环,如果一个网页三秒钟打不开,很多人就会离开,性能优化也是程序高效运行的保障。
我们优化的对象是什么?

优化对象是程序,以及程序所运行在的载体(如浏览器)

我们已经知道了性能优化的对象是什么了,那么接下来就可以根据优化对象分开几个大类总结,对于前端来说,程序和载体无非以下5点:

html
css
js
程序相关的工具
浏览器

这样我们再展开去说就能说的清楚,不会遗漏。
总结每个大类的时候,先从整个文档格式开始,再到外部资源,再到代码层面
1. html
html应该首先想到语义化标签,正确的语义化可以我们的文档结构更加清晰。

语义化标签,结构清晰
js文件正确放置,防止阻塞

2.css

css文件应该放在body标签顶部,防止页面二次渲染而抖动。
当小图片多的时候可以使用雪碧图,减少页面请求。
公共的css抽离,代码复用
多个css合并,减少HTTP请求
选择器优化嵌套,尽量避免层级过深,缩短查找过程
充分利用css继承属性,减少代码量
减少页面的重绘,可以先用一个变量操作所有样式后,最后一步把这个变量关联到dom上

3.js      总结(语义化标签,结构清晰;css文件应该放在body标签顶部,防止页面二次渲染而抖动。当小图片多的时候可以使用雪碧图,减少页面请求。公共的css抽离,代码复用,抽离公共的js,代码复用;抽离公共的组件,代码复用;定时器记得清除,较少内存的耗用
v-if和v-show正确使用,较少页面dom的构建;节流、防抖,防止意外的触发;v-for 遍历 添加 key,且避免同时使用 v-if;路由懒加载;图片懒加载;)

抽离公共的js,代码复用
抽离公共的组件,代码复用
定时器记得清除,较少内存的耗用
v-if和v-show正确使用,较少页面dom的构建
节流、防抖,防止意外的触发
长列表滚动到可视区域动态加载(大数据渲染)
computed 和 watch 区分使用场景,减少性能消耗
v-for 遍历 添加 key,且避免同时使用 v-if

4.webpack

去除代码注释,压缩程序
Webpack 对图片进行压缩-------先引入npm install image-webpack-loader --save-dev,然后在 webpack.config.js 中配置
减少 ES6 转为 ES5 的冗余代码
提取公共代码
模板预编译
优化 SourceMap
构建结果输出分析
使用webpack-bundle-analyzer查看项目所有包及体积大小

5. 浏览器

首屏加载loading,优化体验
使用缓存,减少重复请求
启用gzip压缩,减少请求
使用cnd,缩短请求链
使用图片懒加载,组件懒加载,路由懒加载,减少请求
第三方插件的按需引入
服务端渲染 SSR or 预渲染
使用 Chrome Performance 查找性能瓶颈,针对性的优化

VUE-----------------------------------------------------------------------------------------------------

76. 什么是MVVM?

MVVM 分为 Model、View、ViewModel 三者。
Model 和 View 通过 ViewModel 来进行联系的 采用双向绑定(data-binding)这种模式实现了 Model 和 View 的数据自动同步,因此开发者只需要专注对数据的维护操作即可,而不需要自己操作 dom。

77. 说出至少 4 中 vue 当中的指令和它的用法?

v-if:判断是否为真,然后重组、销毁 DOM 节点 

v-for:数据循环 

v-bind:v-bind用来绑定数据和属性以及表达式

v-model:实现双向绑定 

v-on:添加事件  v-on 指令用于绑定HTML事件 :v-on:click 缩写为 @click

v-on可以监听多个方法吗?

  • 可以,比如 v-on=“onclick,onbure”

v-else:配合 v-if 使用

自定义指令:使用vue.dirctive。// 注册一个全局自定义指令 v-focus 该指令的功能是在页面加载时,元素获得焦点 Vue.directive('focus', { // 当绑定元素插入到 DOM 中。 inserted: function (el) { // 聚焦元素 el.focus()

全局自定义指令和局部自定义指令

1.首先我们来看全局自定义指令 :用Vue.directive来注册。

比如一个input自动聚焦的例子:在main.js中写入以下内容:

// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {
  // 当被绑定的元素插入到 DOM 中时……
  inserted: function (el) {
    // 聚焦元素
    el.focus()
  }
})

2.然后我们来看局部自定义指令 :通过在组件内设置directives属性


directives: {
  focus: {
    // 指令的定义
    inserted: function (el) {
      el.focus()
    }
  }
}

使用的时候要在自定义的指令前面加上v-,然后你可以在模板中任何元素上使用新的 v-focus :

78. Vue 中的Key 的作用                                                                                                 

做一个唯一标识。key的作用主要是为了高效的更新虚拟DOM。key值是在DOM树进行diff算法(同层的树节点进行比较)时候发挥作用。一个是用来判断新旧Vnode(虚拟DOM)是否为同一个,从而进行下一步的比较以及渲染。另外一个作用就是判断组件是否可以复用,是否需要重新渲染。

79.v-for和v-if为什么不能一起使用

v-for比v-if优先级高,同时作用在同一个元素上,(每次渲染都会先循环再进行条件判断)这意味着 v-if 将分别重复运行于每个 v-for 循环中带来性能上的浪费。需要v-if 置于外层元素或在外层嵌套template(页面渲染不生成dom节点),在这层进行v-if判断,然后在内部进行v-for循环。

80. Vue 组件data 为什么必须是函数?

因为组件是可以复用的, JS 里对象是引用关系, 如果组件 data 是一个对象, 那么子组件中的 data 属性值 会互相污染, 产生副作用。
所以一个组件的 data 选项必须是一个函数, 因此每个实例可以维护一份被返回对象的独立拷贝。new Vue 的实例是不会被复用的,因此不存在以上问题。

81. el:作用:决定以后Vue实例会管理哪个DOM

82.  虚拟DOM

用普通js对象来描述DOM结构  ,以对象嵌套的方式来表示 dom 树及其层级结构,那么每次 dom 的更改就变成了对 js 对象的属性的增删改查,这样一来性能开销小。因为不是真实DOM,所以称之为虚拟DOM,

83. vue双向绑定的原理

vue的双向绑定是采用数据劫持结合发布者-订阅者模式的方法,通过object,define.property()来劫持各个属性的setter和getter,在数据发生变化时发布消息给订阅者,触发相应的监听回调。

不能监听到对象属性的监听添加和删除,需要vue.set()来添加和删除

84. computed 和 watch 有什么区别及运用场景?

区别: computed 计算属性: 依赖其它属性值, 并且computed 的值有缓存, 只有它依赖的属性值发生改变, 下一 次获取 computed 的值时才会重新计算computed 的值        。不支持异步            

watch
1、watch是监听器,可以监听某一个数据,然后执行相应的操作;
2、不支持缓存,数据变直接会触发相应的操作;
3、监听的函数接收两个参数,第一个参数是最新的值;第二个参数是输入之前的值;
4、支持异步操作; 

methods:表示一系列具体的操做,适合书写大量的业务逻辑

当一个属性受多个属性影响的时候,使用computed-------购物车商品结算。watch----当一条数据影响多条数据的时候,使用watch-------搜索框。

85、Axios

是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。

在vue中用axios进行网络请求。 这个是vue的作者推荐使用的

功能特点:

支持promise API

支持拦截请求和响应

支持转换请求和响应数据

axios有哪些常用方法?
一、axios.get(url[, config])   //get请求用于列表和信息查询
二、axios.delete(url[, config])  //删除
三、axios.post(url[, data[, config]])  //post请求用于信息的添加
四、axios.put(url[, data[, config]])  //更新操作

axios是通过promise实现对ajax技术的一种封装,新建一个Axios对象时,会有两个拦截器。request拦截器,response拦截器。

  1. 请求拦截器
    请求拦截器的作用是在请求发送前进行一些操作,例如在每个请求体里加上token,统一做了处理如果以后要改也非常容易。
axios.interceptors.request.use(function (config) {
    // 在发送请求之前做些什么,例如加入token
    .......
    return config;
  }, function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
  });
  1. 响应拦截器
    响应拦截器的作用是在接收到响应后进行一些操作,例如在服务器返回登录状态失效,需要重新登录的时候,跳转到登录页。

axios.interceptors.response.use(function (response) {
    // 在接收响应做些什么,例如跳转到登录页
    ......
    return response;
  }, function (error) {
    // 对响应错误做点什么
    return Promise.reject(error);
  });

3、说下你了解的axios相关配置属性?
答:
url是用于请求的服务器URL

method是创建请求时使用的方法,默认是get

baseURL将自动加在url前面,除非url是一个绝对URL。它可以通过设置一个baseURL便于为axios实例的方法传递相对URL

transformRequest允许在向服务器发送前,修改请求数据,只能用在'PUT','POST'和'PATCH'这几个请求方法

headers是即将被发送的自定义请求头
headers:{'X-Requested-With':'XMLHttpRequest'},

params是即将与请求一起发送的URL参数,必须是一个无格式对象(plainobject)或URLSearchParams对象
params:{
ID:12345
},

auth表示应该使用HTTP基础验证,并提供凭据
这将设置一个Authorization头,覆写掉现有的任意使用headers设置的自定义Authorization
auth:{
username:'janedoe',
password:'s00pers3cret'
},

'proxy'定义代理服务器的主机名称和端口
auth表示HTTP基础验证应当用于连接代理,并提供凭据
这将会设置一个Proxy-Authorization头,覆写掉已有的通过使用header设置的自定义Proxy-Authorization头。
proxy:{
host:'127.0.0.1',
port:9000,
auth::{username:'mikeymike',password:'rapunz3l'}},


Ajax可以实现动态不刷新(局部刷新)
就是能在不更新整个页面的前提下维护数据。这使得Web应用程序更为迅捷地回应用户动作,并避免了在网络上发送那些没有改变过的信息

86.  什么是Vue 生命周期

          1、什么是vue生命周期?
         答: Vue 实例从创建到销毁的过程,就是生命周期。

           2、vue生命周期的作用是什么?
            答:它的生命周期中有多个事件钩子,让我们在控制整个Vue实例的过程时更容易形成好的逻辑。

          3、vue生命周期总共有几个阶段?
          答:它可以总共分为8个阶段:创建前/后, 载入前/后,更新前/后,销毁前/销毁后。

            4、第一次页面加载会触发哪几个钩子?
            答:第一次页面加载时会触发 beforeCreate, created, beforeMount, mounted 这几个钩       子。

            5、DOM 渲染在 哪个周期中就已经完成?
            答:DOM 渲染在 mounted 中就已经完成了。

            6、生命周期的含义:

beforecreate:el 和 data 并未初始化,还不能访问data、computed、watch、methods上的方法和数据    可以在这加个loading加载事件,在加载实例时触发
created:完成了 data 数据的初始化,el没有,可以访问到data、computed、watch、methods上的方法和数据,在这里结束loading加载事件,可以做前后端的交互, 例:异步请求如ajax
beforeMount:完成了 el 和 data 初始化

mounted
当前生命周期el已经挂载到文档里   可以操作DOM节点

beforeUpdate
在数据更新之前调用,发生在虚拟DOM重新渲染和打补丁之前。可以在该钩子中进一步地更改状态,不会触发附加的重渲染过程。

updated
当前生命周期更新的数据与模板结合完毕    可以做一个确认停止事件的确认框

beforeDestroy
在实例销毁之前调用。实例仍然完全可用。当前生命周期做一些移除的操作。例:监听的移除,定时器的移除,事件的解绑

destroyed
在实例销毁之后调用。调用后,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不被调用。

7、简单描述每个周期具体适合哪些场景?

生命周期钩子的一些使用方法:
beforecreate : 可以在这加个loading事件,在加载实例时触发 ;
created : 初始化完成时的事件写在这里,如在这结束loading事件,异步请求也适宜在这里调用 ;
mounted : 挂载元素,获取到DOM节点 ;
updated : 如果对数据统一处理,在这里写上相应函数 ;
beforeDestroy : 可以做一个确认停止事件的确认框 ;
nextTick : 更新数据后立即操作dom;

created和mounted的区别
答:created:在模板渲染成html前调用,即通常初始化某些属性值,然后再渲染成视图。
mounted:在模板渲染成html后调用,通常是初始化页面完成后,再对html的dom节点进行一些需要的操作。

父子组件的生命周期中,首先走父组件的生命周期,当父组件的生命周期走完beforeMount(挂在前)这个函数时就会走子组件的生命周期,当子组件挂载完成后(执行完mounted)父组件在挂载dom节点。

vue获取数据在哪个周期函数
答:一般 created/beforeMount/mounted 皆可.
比如如果你要操作 DOM , 那肯定 mounted 时候才能操作.

调接口在哪个周期:created、mounted

87.keep-alive

使被包含的组件保留状态,或避免重新渲染 。也就是所谓的组件缓存。当用了keep-alive以后会多两个生命周期。deactivat、activatede.如果使用了keep-alive在第一次加载会执行五个生命周期。第二次或第n次进入只执行deactivat、 activatede

88. v-show 和v-if 指令的共同点和不同点

v-show 指令是通过修改元素的 display 的 属性让其显示或隐藏
v-if 指令是直接销毁和重建 DOM 节点,达到让元素显示和隐藏的效果

89.echarts 分辨率  

有个resize()

前端面试题_第9张图片

90.什么是Vuex? 

答:Vuex是为vue.js应用程序开发的状态管理工具。应用遇到多个组件共享状态时,使用vuex。场景:多个组件共享数据或者是跨组件传递数据时。每一个vuex应用核心就是store(仓库)。store基本上就是一个容器,它包含着你的应用中大部分的state(状态)

安装 npm i vuex --save/...在src文件目录下新建store>index.js文件

import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
const store = new Vuex.Store();
 
export default store;xl

const store = new Vuex.Store({...});

2.Vuex解决了什么问题?

答:多个组件共享数据或者是跨组件传递数据时。

3.vuex使用与什么场景?

答:单页应用中,组件之间的状态。音乐播放、登录状态、加入购物车
4.vuex有哪几种属性?

答:state、getters、mutations、actions、modules 。

①state:vuex的基本数据,用来存储变量(state:{userId:''}),在vue中使用this.$store.state.userid

②getter:从基本数据(state)派生的数据,相当于state的计算属性,具有返回值的方法。getter:{userIdDouble:function(state){return state.userId×2}在vue中使用this.$store.getters.useridDouble

③mutation:提交更新数据的方法,必须是同步的(如果需要异步使用action)。在Vuex中修改数据只能在Mutations中,不能再其他地方修改。不能直接调用一个 mutations 中的处理函数 要使用this.$store.commit(“mutations中你要修改的函数名”) 来进行调用

mutations: {
    SET_USER: (state, userId) => {
      state.userId = "我被修改了“
    },
  },

commit:同步操作,写法: this.$store.commit(‘SET_USER’)

在实际项目中往往会有值传递给Mutations 给store.commit传一个附加参数,他就叫做mutation的载荷
也就是你在调用vuex中的方法的同时,可以传递一个参数过去,对vuex中的数据进行了修改
如果需要传递多个参数可以直接传递一个对象如:
 列如:this.$store.commit('SET_USER','我是传递过来的数据')、、、

mutations: {
    SET_USER: (state, newmsg) => {
      state.useId =newmsg  /newmsg接受了传递过来的数据将数据复制给了state中的userId
    }  },

回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数,提交载荷作为第二个参数

④. action:和mutation的功能大致相同,不同之处在于 ==》1. Action 提交的是 mutation,而不是直接变更状态。 2. Action 可以包含任意异步操作。

  actions: { // {} 是es6中解构,把对象解构成属性
    login({ commit }, value) {
      commit('SET_USER', value)
      // commit('SET_TOKEN', value2) },}

dispatch:异步操作,写法: this.$store.dispatch(‘mutations方法名’,值)
⑤. modules:模块化vuex,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理。
简单来说就是可以把以上的 state、mutation、action、getters 整合成一个user.js,然后放到store.js里面

5.Vuex中状态储存在哪里,怎么改变它?

答:存储在state中,改变Vuex中的状态的唯一途径就是显式地提交 (commit) mutation。

6.Vuex中状态是对象时,使用时要注意什么?

答:对象是引用类型,复制后改变属性还是会影响原始数据,这样会改变state里面的状态,是不允许,所以先用深度克隆复制对象,再修改。

7.怎么在组件中批量使用Vuex的state状态?

答:使用mapState辅助函数, 利用对象展开运算符将state混入computed对象中

import {mapState} from 'vuex' export default{ computed:{ ...mapState(['price','number']) } }

8.Vue.js中ajax请求代码应该写在组件的methods中还是vuex的actions中?
答:如果请求来的数据是不是要被其他组件公用,仅仅在请求的组件内使用,就不需要放入vuex 的state里。
如果被其他地方复用,这个很大几率上是需要的,如果需要,请将请求放入action里,方便复用。

91、vuex如何保持登录状态

登录后用户信息用mutation储存到vuex的states里,然后在beforeach里面从state里把状态取出来,这样就避免每跳一个路由就要登录。但是在页面刷新的时候会丢失数据。所有存的就全部都丢失,刷新了,所以额外加了一个用localstorage,如果用sessionstorage的话,你当前页面一关下个页面你就还要再登,我们项目里其实用的是localstorage,就是说在state里面也去存,也在localstorage里面也去存。

92、async和,await

Async  await 是用来使异步操作同步化的,比如项目需求里有的流程需要按照顺序去执行异步请求,就可以使用await去阻塞后面的代码,确保请求按照我们想要的顺序执行。

1.会自动将常规函数转换成Promise,返回值也是一个Promise对象
2.只有async函数内部的异步操作执行完,才会执行then方法指定的回调函数
3.异步函数内部可以使用await
4.await 放置在Promise调用之前,await 强制后面点代码等待,直到Promise对象resolve,得到resolve的值作为await表达式的运算结果
5.await只能在async函数内部使用,用在普通函数里就会报错

93、vue单向数据流

父传子数据,在子组件中不能修改会报错,如果要修改,需要在子组件新建一个data属性,进行修改。vuex是单向数据流

94、通信方式。常见使用场景可以分为三类:

父子通信: 父向子传递数据是通过 props,子向父是通过 $emit;通过 $parent / $children 通信;$ref 也可以访问组件实例(为子组件赋予一个ID引用,父组件用来访问子组件实例或子元素

1、在子组件中:

是必须要存在的 2、在父组件中:首先要引入子组件 import Child from './child';3、 是在父组件中为子组件添加一个占位,ref="mychild"是子组件在父组件中的名字4、父组件中 components: {  是声明子组件在父组件中的名字 5、在父组件的方法中调用子组件的方法,很重要   this.$refs.mychild.parentHandleclick("嘿嘿嘿");

);provide / inject ;$attrs / $listeners;

兄弟通信: EventBus;Vuex;

跨级通信: EventBus;Vuex;provide / inject ;$attrs / $listeners;

95、 nextTick

是将回调函数延迟在下一次dom更新数据后调用,简单的理解是:当数据更新了,在dom中渲染后,自动执行该函数,

Vue生命周期的created()钩子函数进行的DOM操作一定要放在Vue.nextTick()的回调函数中,原因是在created()钩子函数执行的时候DOM 其实并未进行任何渲染,而此时进行DOM操作无异于徒劳,所以此处一定要将DOM操作的js代码放进Vue.nextTick()的回调函数中

96、git的常用指令

拉取远程仓库:$ git pull [remoteName] [localBranchName]

推送远程仓库:$ git push [remoteName] [localBranchName]

查看本地分支:$ git branch

查看所有分支:$git branch -a

查看远程分支:$ git branch -r

新建分支:git checkout -b '分支名称'

新建本地分支与远程分支关联

git branch –set-upstream 本地新建分支名 origin/远程分支名

拉取远程分支并创建本地分支 git checkout -b 本地分支名x origin/远程分支名x

切换到master分支上  git checkout master

一.git提交代码简单流程

第一次使用前的指令:

git config user.name [用户名]    第一次使用前,需要配置用户名

git config user.email [邮箱]    第一次使用前,需要配置邮箱

git clone [git的仓库地址]    克隆git仓库代码

 

开发常用指令:

git status  查看有变更的文件

git diff [文件名] / .   查看文件修改内容/查看所有文件修改内容

git add [文件名] / .   提交文件/所有文件到暂存区

git checkout [文件名]   撤销文件修改

git commit -m '提交信息'    提交文件到仓库区

git log   查看提交记录

git pull origin [分支名]    拉取远程分支的最新代码,在push之前最好进行这个指令

git push origin [分支名]   上传本地指定分支到远程仓库

 

多人开发常用指令:

git cheackout [分支名]     切换到分支

git checkout -b [分支名]   创建并且切换到新分支上

git branch   查看分支

git merge [分支名]    合并分支

是把要合并的分支合并到当前分支上,注意当前分支是哪条分支
如果有冲突conflict用vscode解决冲突
merge之后需要进行 git commit -m '提交信息' 

Git提交代码步骤

1.1 第1步:同步远程仓库代码:git pull

1.2 第1步:查看当前状态:git status

1.3 第2步:提交代码到本地git缓存区:git add

1.4 第3步:推送代码到本地git库:git commit   git commit 文件名 -m "提交代码备注"

1.5 第5步:提交本地代码到远程仓库:git push

git解决冲突步骤

git命令在提交代码前,没有pull拉最新的代码,因此再次提交出现了冲突

1、git stash (这是将本地代码回滚值至上一次提交的时候,就是没有你新改的代码)。

2、git pull origin master(将远程的拉下来)。

3、git stash pop(将第一步回滚的代码释放出来,相等于将你修改的代码与下拉的代码合并)。

然后解决冲突,你本地的代码将会是最新的代码。

4、git add .

5、git commit -m""。

6、git push origin master。

这几步将代码推至了远程,最后再git pull origin master 一下,确保远程的全部拉下来。

提交代码

  1. git stash //暂存代码
  2. git pull 分支名//从远程仓库拉取最新代码
  3. git stash pop //合并代码到本地仓库 此时代码是将暂存的代码和远程仓库的代码合并

合并分支:

合并步骤:
1、进入要合并的分支(如开发分支合并到master,则进入master目录)
git checkout master
git pull

2、查看所有分支是否都pull下来了
git branch -a

3、使用merge合并开发分支
git merge 分支名

4、查看合并之后的状态
git status

添加:$git add

撤销:$git reset

创建本地分支:$ git branch [name] ----注意新分支创建后不会自动切换为当前分支

写完代码要先拉取,再推送

前端面试题_第10张图片

1.3提交时发生冲突如何解决?

        原因:

        因为在合并分支的时候,master和dev分支恰好有人都修改了同一个文件,git不知道以哪一个文件为准,就产生了冲突。

        解决:

        发生冲突时,对比本地文件和远程分支上的文件,然后把远程分支上的内容手工修改到本地文件,然后再提交冲突文件。必要时可以和同时沟通。

git stash  //把工作区的修改提交到栈区,目的是保存工作区的修改
git pull  //拉取远程分支上的代码并合并到本地分支,目的是消除冲突
git stash pop  //把保存在栈区的修改部分合并到最新的工作空间中\

97、开发流程

产品宣贯。然后UI根据产品宣贯的东西出UI图,后端出后端设计,然后后端设计评审。前端前期根据UI设计画图,后期和后端进行接口联调。然后提测,出几个版本。缺陷收敛了之后再发布上线.前期。后端会先给我提供假数据方便我们开发,这样接口联调的时候会快一些

98.单页面y应用的优缺点

单页面应用(SPA),通俗一点说就是指只有一个主页面的应用,浏览器一开始要加载所有必须的 html, js, css。所有的页面内容都包含在这个所谓的主页面中。
多页面(MPA),就是指一个应用中有多个页面,页面跳转时是整页刷新

单页面的优点:
1,用户体验好,快,内容的改变不需要重新加载整个页面,基于这一点spa对服务器压力较小
2,前后端分离
3,页面效果会比较炫酷(比如切换页面内容时的专场动画)

单页面缺点:
1,不利于seo

2.不可以使用浏览器的导航按钮需要自行实现前进后退

3,初次加载时耗时多
4,页面复杂度提高很多

99. 路由的使用

1.安装  2.配置相关信息:引用(import)   通过vue.use(插件),安装    创建VueRouter对象。  将router对象传入到实例中(导出再main.js中导入)

路由的默认路径:const routes = [{path:'',     (//redirect 重定向) redirect:'/home},

history模式:传入mode:'history'

的属性:  to=“”属性  用于指定跳转路径        tag属性(tag=""button)指定之后渲染成什么组件,默认是    replace属性    默认是可以返回的。加上replace属性不可返回         

active-class是router-link终端属性,用来做选中样式的切换,当router-link标签被点击时将会应用这个样式

路由之间是怎么跳转的?有哪些方式

1.

2、this.$router.push()跳转到指定的url,并在history中添加记录,点击回退返回到上一个页面

3、this.$router.replace()跳转到指定的url,但是history中不会添加记录,点击回退到上上个页面

4、this.$touter.go(n)向前或者后跳转n个页面,n可以是正数也可以是负数

this.$router.push('/home')/this.$router.replace('/home')页面也会通过路由跳转

1、 this.$router.push进行编程式路由跳转

    2、 router-link 进行页面按钮式路由跳转

    3、 this.$route.params获取路由传递参数

    4、this.$route.query获取路由传递参数

路由传参三种方式:第一种(页面刷新不会丢失):直接调用$router.push实现携带参数的跳转 this.$router.push({path:'/particulars/${id}'.需要在path中添加/:id来对应 $router.push 中path携带的参数。子组件中获取传递的参数值:this.$route.params.id

第二种(页面刷新数据会丢失):通过路由属性中的name来确定匹配的路由,通过params来传递参数。this.$router.push({name:'particulars',params:{id:id})

对应路由配置: 注意这里不能使用:/id来传递参数了,因为组件中,已经使用params来携带参数了.

path:'/particulars', name:'particulars', component:particulars

子组件中获取传递的参数值:this.$route.params.id

第三种方法:使用path来匹配路由,然后通过query来传递参数this.$router.push({path:'particulars',query:{id:id})
这种情况下 query传递的参数会显示在url后面?id=?

path:'/particulars', name:'particulars', component:particulars

子组件中获取传递的参数值:this.$route.query.id

路由懒加载    将路由对应的组件打包成一个个的js代码块,只有在这个路由被访问到的时候,才加载对应的组件。const routes=[{path:'/home', compoent: ()=>import('/..components/Home'}

路由嵌套:实现路由嵌套有两个步骤:①创建对应子组件,并且在路由映射中配置相应的 子路由②组件内部使用标签。

路由嵌套:

{path:'/home',
component:Home,
children:[
{path:'new',
component:HomeNews}]

$route和$router的区别:$router为VueRouter实例,想要导航到不同URL,则使用$router.push方法      $route对象表示当前的路由信息里面可以获取name、path、query、params等

导航守卫:全局守卫:beforeEach   afterEach

前置守卫(guard):跳转前回调:beforeEach。必须调用next()函数。回调函数中的参数,to:进入到哪个路由去,from:从哪个路由离开,next:函数,决定是否展示你要看到的路由页面。

前端面试题_第11张图片

1. beforeEnter:(to,from,next)=>{},用法与全局守卫一致。只是,将其写进其中一个路由对象中,只在这个路由下起作用。

路由有嵌套的时候:前端面试题_第12张图片

后置钩子(hook):跳转后回调。也就是afterEach,不需要主动调用next()函数

问你路由守卫你就说,我们项目里用过全局前置守卫 beforeEach 用来在路由跳转前确认用户是否登录,是否拥有这条路由的权限。还有就是组件内守卫beforeRouteleave,用来在用户发作业流程中退出,给他弹二次确认弹窗,确认是否要退出用的

100、vue项目中实现用户登录及token验证

在前后端完全分离的情况下,Vue项目中实现token验证大致思路如下:

1、第一次登录的时候,前端调后端的登陆接口,发送用户名和密码

2、后端收到请求,验证用户名和密码,验证成功,就给前端返回一个token

3、前端拿到token,将token存储到localStorage和vuex中,并跳转路由页面

4、前端每次跳转路由,就判断 localStroage 中有无 token ,没有就跳转到登录页面,有则跳转到对应路由页面

5、每次调后端接口,都要在请求头中加token

6、后端判断请求头中有无token,有token,就拿到token并验证token,验证成功就返回数据,验证失败(例如:token过期)就返回401,请求头中没有token也返回401

7、如果前端拿到状态码为401,就清除token信息并跳转到登录页面

101. history和hash模式

1.hash模式
特点:在url地址上有#号
实现的原理:原生的hasChange事件来实现,来监听hash值的变化
window.onhaschange=function(){}
刷新页面的时候:不会去发送请求,页面不会有任何问题,不需要后端来配合

2.history模式
特点:在url地址上没有#号,比较与hash模式看起来好看一些
实现的原理:利用的是history的api 来实现的 popState() 来实现的
刷新页面的时候:会去发送请求然后会导致页面出现找不到的情况,需要后端来配合解决

102、import 和require的区别

import 是 ES6 的模块化语法。require 是赋值过程并且是运行时才执行, import 是解构过程并且是编译时执行。require可以理解为一个全局方法,所以它甚至可以进行下面这样的骚操作,是一个方法就意味着可以在任何地方执行。而import必须写在文件的顶部。require的性能相对于import稍低,因为require是在运行时才引入模块并且还赋值给某个变量,而import只需要依据import中的接口在编译时引入指定模块所以性能稍高3.在commom.js 中module.export 之后 导出的值就不能再变化,但是在es6的export中是可以的。

父子组件生命周期顺序

父beforeCreate -> 父created -> 父beforeMount -> 子beforeCreate -> 子created -> 子beforeMount -> 子mounted -> 父mounted

103.你都做过哪些 Vue 的性能优化?
这里只列举针对 Vue 的性能优化,整个项目的性能优化是一个大工程。

对象层级不要过深,否则性能就会差。
不需要响应式的数据不要放在 data 中(可以使用 Object.freeze() 冻结数据)
v-if 和 v-show 区分使用场景
computed 和 watch 区分场景使用
v-for 遍历必须加 key,key最好是id值,且避免同时使用 v-if
大数据列表和表格性能优化 - 虚拟列表 / 虚拟表格
防止内部泄露,组件销毁后把全局变量和时间销毁
图片懒加载
路由懒加载
异步路由
第三方插件的按需加载
适当采用 keep-alive 缓存组件
防抖、节流的运用
服务端渲染 SSR or 预渲染

104、axios在项目中的应用

Axios是AJAX的封装,基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。

  • vue项目中使用ajax时需要axios插件

  • 下载方式cnpm install axios --save

import axios from './index'
const preUrlPath = _global.config.API_HOST
/**
* 查询全部数据
* @param params
* @returns {*}
*/
const getData = (params) => {
return axios.get(preUrlPath + '/rest/system/capabilityEvaluation/capabilityEvaluation', {params: params})
}
/**
* 查询全部数据
* @param params
* Put
* @returns {*}
*/
const updateData = (params) => {
return axios.post(preUrlPath + '/rest/system/capabilityEvaluation/capabilityEvaluation', params)
}

105、吸顶功能

吸顶——滚动吸顶

项目有个滚动吸顶的需求。主要是用到了两个属性。一个是offsettop(当前对象到期上级顶部的距离),一个是scrollTope(页面被卷去的高度,只有可以滚动的页面里有)。通过监听页面的滚动事件。在监听回调里获取scrollTop的值,与offsetTop做对比。当scrollTop>=offsetTop时,使吸顶元素的css样式变为固定定位。小于时,再使吸顶元素回到文档流中。

106、大屏适配

在做大屏可视化项目的时候,一般设计稿会设计成1920*1080,但是页面写死1920*1080在2k、4k等分辨率的屏幕下是不适配的。

适配方式一:

适配方案采用rem布局, 根据屏幕分辨率大小不同,调整根元素html的font-size, 从而达到每个元素宽高自动变化,适配不同屏幕

适配方式二:

等比缩放,css3的transform:scale进行等比缩放

使用 roc-scale-box 组件,vue2与vue3都支持,使用非常简单,引入之后组件内所有内容都会按照设置的宽高比例进行缩放,还有屏幕缩放防抖优化

也适用于项目开发完成后发现需要做适配,引入组件包裹项目根节点即可。

属性:

width 宽度 默认 1920
height 高度 默认 1080
bgc 背景颜色 默认 "transparent"
delay自适应缩放防抖延迟时间(ms) 默认 100
@scaleChange 缩放值发生改变的方法 可动态获取 scale 改变后的值


你可能感兴趣的:(vue.js,css,javascript)