前端面试题(持续更新)

一、HTML  CSS JAVASCRIPT

1.说一下对语义化的理解以及有哪些语义化标签? 

 a、对开发者友好,让人更容易读懂,利于代码可读性,利于维护

 b、对机器友好,让搜索引擎更容易读懂,利于seo

 c、HTML文档结构清晰

语义化标签:<header>、<nav>、<main>、<section>、<article>、<aside>、<footer> 

说一下渐近增强和优雅降级的区别?

  • 渐进增强是针对低版本浏览器也能保证基础功能,然后对高级浏览器改进追加功能;
  • 优雅降级是一开始构建完整功能,再对低版本进行兼容

CSS 优先级和权重值如何计算

!important > 内嵌 1000 >Id 100 > class=[]=伪类 10 > tag=伪元素 1 > ( * + > ~) 0

什么是BFC

块级格式化上下文,可以把BFC看做一个容器,容器里边的元素不会影响到容器外部的元素。

BFC有什么特性?

  1. BFC是一个块级元素,块级元素在垂直方向上依次排列。

  2. BFC是一个独立的容器,内部元素不会影响容器外部的元素。

  3. 属于同一个BFC的两个盒子,外边距margin会发生重叠,并且取最大外边距。

如何创建BFC?

  1. overflow: hidden;
  2. display: flex;
  3. display: inline-flex;
  4. display: inline-block;
  5. position: absolute;
  6. position: fixed;

BFC有什么作用?

1.解决当父级元素没有高度时,子级元素浮动会使父级元素高度塌陷的问题

2.解决子级元素外边距会使父级元素塌陷的问题

css实现一个三角形

.triangle{
  width: 0;
  height: 0;
  border: 100px solid transparent;
  border-left-color: red;
}

px、em、rem、vh、vw分别是什么?

px物理像素,绝对单位;

em相对于自身字体大小,如果自身没有大小则相对于父级字体大小,如果父级也没有则一层一层向上查找,直到找到html为止,相对单位;

rem相对于html的字体大小,相对单位;

vh相对于屏幕高度的大小,相对单位;

vw相对于屏幕宽度的大小,相对单位。

css可继承的属性有哪些?

文本类:text-indent、text-align、line-height、word-spacing、letter-spacing、text-transform、direction、color;

字体类:font、font-family、font-weight、font-size、font-style、font-variant、font-stretch、font-size-adjust;

如何画一条0.5px的线

    background-color: blueviolet;  //背景色
    height: 1px;  //高度为 1px
    width: 200px;  //宽度为 200px
    transform: scale(1,0.5);  //宽度变为原来的1倍,高度变为原来的0.5倍

2.var、let、const有什么区别?

  1. let不具备声明变量提升,var具备声明变量提升
  2. let声明的范围是块作用域,而var声明的范围是函数作用域。
  3. let是ES6才引入的声明关键字
  4. for循环中的let声明
  5. const与let很相似,最大的区别是const必须初始化,且不能再次赋值。

总结:不使用var,有了let和const,大多数开发者会发现自己不再需要var了,限制自己只使用let和const,有助于提升代码质量,因为变量有了明确的作用域、声明位置、以及不变的值。
const优先,let次之。使用const声明可以让浏览器运行时强制保持变量不变,也可以让静态代码分析工具提前发现不合法的赋值操作。

3.说一说flex布局是什么?以及他有哪些属性?

1.是一个弹性盒子布局,自动弹性伸缩,适配不同大小的屏幕

2.flex-direction 主轴方向:

   row(默认值):主轴为水平方向,起点在左端。

   row- reverse:主轴为水平方向,起点在右端。

   column:主轴为垂直方向,起点在上沿。     

   column-reverse:主轴为垂直方向,起点在下沿。

3.flex-wrap 主轴一行满了换行:

   nowrap: 不换行压缩宽度

   wrap: 换行

   wrap-reverses: 反向换行

4.justify-content 主轴元素对齐方式

  flex-start: 靠着main-start对齐//参考常见术语(一般是左方向)
  flex-end:   靠着main-end对齐//参考常见术语(一般是右方向)
  center:     靠着主轴居中对齐//一般就是居中对齐
  space-between: 两端对齐,靠着容器壁,剩余空间平分
  space-around:  分散对齐,不靠着容器壁,剩余空间在每个项目二侧平均分配
  space-evenly:  平均对齐,不靠着容器壁,剩余空间平分
5.align-content 交叉轴行对齐方式 多行

   flex-start (每一行)(默认)靠着cross-start对齐//参考常见术语(一般是左方向)
   flex-end   (每一行)靠着cross-end对齐//参考常见术语(一般是右方向)
   center     (每一行)靠着cross线居中对齐//一般就是居中对齐
   space-between (每一行)两端对齐,靠着容器上下壁,剩余空间平分
   space-around  (每一行)分散对齐,不靠着容器壁,剩余空间在每个项目二侧平均分配
   strentch      (每一行)伸缩,占满整个高度
 

4.盒子模型包含

普通盒子(W3C):box-sizeing:content-box;盒子宽度 = content + padding + border + margin

IE:box-sizeing:border-box;盒子宽度 = content + margin(padding 和 border 都会计算在 content 内部)

5.{visibility: hidden)和{display: none)有什么区别?

display:none:

a、该元素不占据任何空间,在文档渲染时,该元素如同不存在(但依然存在文档对  象模型树中),

b、会触发reflow(重排),进行渲染。

visibility:hidden:

a、该元素空间依旧存在。

b、只会触发repaint(重绘),因为没有发现位置变化,不进行渲染。

6.如何实现实时通信?

轮询:轮询是客户端和服务器之间会一直进行连接,每隔一段时间就询问一次。其缺点也很明显:连接数会很多,一个接受,一个发送。而且每次发送请求都会有Http的Header,会很耗流量,也会消耗CPU的利用率。

优点:就是实现简单,无需做过多的更改。

缺点:是轮询的间隔过长,会导致用户不能及时接收到更新的数据;轮询的间隔过短,会导致查询请求过多,增加服务器端的负担

长轮询:是对轮询的改进版,客户端发送HTTP给服务器之后,如果没有新消息,就一直等待。有新消息,才会返回给客户端。在某种程度上减小了网络带宽和CPU利用率等问题。由于http数据包的头部数据量往往很大(通常有400多个字节),但是真正被服务器需要的数据却很少(有时只有10个字节左右),这样的数据包在网络上周期性的传输,难免对网络带宽是一种浪费。

优点:是做了优化,有较好的时效性。

缺点:是保持连接会消耗资源; 服务器没有返回有效数据,程序超时。

 iframe:流方式是在页面中插入一个隐藏的iframe,利用其src属性在服务器和客户端之间创建一条长连接,服务器向iframe传输数据(通常是HTML,内有负责插入信息的javascript),来实时更新页面。

优点:消息能够实时到达;浏览器兼容好。

缺点:服务器维护一个长连接会增加开销;IE、chrome、Firefox会显示加载没有完成,图标会不停旋转。

 WebSocket:类似Socket的TCP长连接的通讯模式,一旦WebSocket连接建立后,后续数据都以帧序列的形式传输。

优点:在客户端断开WebSocket连接或Server端断掉连接前,不需要客户端和服务端重新发起连接请求。在海量并发和客户端与服务器交互负载流量大的情况下,极大的节省了网络带宽资源的消耗,有明显的性能优势,且客户端发送和接受消息是在同一个持久连接上发起,实时性优势明显。

缺点:浏览器支持程度不一致,不支持断开重连。

SSE(Server-Sent Event):建立在浏览器与服务器之间的通信渠道,然后服务器向浏览器推送信息。SSE 是单向通道,只能服务器向浏览器发送,因为 streaming 本质上就是下载。

优点:SSE 使用 HTTP 协议,现有的服务器软件都支持。SSE 属于轻量级,使用简单;SSE 默认支持断线重连;

使用场景

轮询适用于:小型应用,实时性不高

长轮询适用于:一些早期的对及时性有一些要求的应用:web IM 聊天

iframe适用于:客服通信等

WebSocket适用于:微信、网络互动游戏等

SSE适用于:金融股票数据、看板等

7.在项目中如何性能优化?

静态资源优化:

  • 图片的应用场景和使用

  • html、css、js的具体优化策略

  • 资源文件的优化:比如文件压缩合并策略、打包方案、版本号更新方案

  • 前端工程化工具等。

优化网络连接:

  • 使用CDN:CDN是内容分发网络,它能够实时地根据网络流量和各个节点的连接、负载状况以及到用户的距离和响应时间等综合信息将用户的请求重新导向离用户最近的服务节点上,其目的是使用户可以就近的取得所需内容,解决网络拥挤的状况,提高网站的响应速度

  • 使用DNS预解析:当浏览器访问一个域名的时候,需要解析一次DNS,获得对应域名的ip地址,在解析过程中,按照浏览器缓存、系统缓存、路由器换算、DNS缓存、域名服务器的顺序,逐步读取缓存,直到拿到ip地址

  • 持久连接:使用keep-alive或者persistent来建立持久连接,降低了延时和连接建立的开销

减少资源大小:

  • 图片的压缩

  • html、css文件的压缩。

webpack性能优化:

  • 打包公共代码

  • 动态导入和按需加载:webpack提供了两种技术通过模块内联函数用来分离代码,优先选择的方式是ECMAScript提案的import()语法,第二种则是使用webpack特定的require.ensure

  • 长缓存优化:1、将hash替换成chunkhash,这样当chunk不变的时候,缓存依然有效
    2、使用Name而不是id

8.Less和Scss原理和区别

原理:

Less定义:是一种动态的样式语言,使CSS变成一种动态的语言特性,如变量、继承、运算、函数。Less既可以在客户端上面运行(支持IE6以上版本、Webkit、Firefox),也可以在服务端运行(Node.js)

SaSS定义:是一种动态样式语言,SaSS里面的语法属于缩排语法,对于之前的css相比,多出了很多功能,更容易阅读

区别:

编译环境:Scss是在服务端上面处理的,Less在编译时,需要引入less.js来处理Less代码输出CSS到浏览器上,也可以在开发服务器上将Less语法编译成css文件,输出CSS文件到生产包目录,也有在线编译地址。

变量符: Less是@,而Scss是$

//Less-变量定义
@color: #008c8c; 
#header{
  border: 1px solid @color; 
}
//scss-变量定义
$color: #008c8c;

#header{
  border: 1px solid $color; 
}

输出设置: 

Less没有输出设置

Sass有4种输出选项:
     nested:嵌套缩进的css代码
     expanded:展开的多行css代码
     compact:简洁格式的css代码
     compressed:压缩后的css代码
Sass支持条件语句,可以使用if{}else{},for{}循环等等

Less不支持

总体优点:   

 1 提供CSS缺失的样式层复用机制
 2 减少冗余代码
 3 提高样式代码的可维护性
 4 结构清晰,便于扩展可以方便的屏蔽浏览器私有的语法差异
 5 轻松实现多重继承,完全兼容了CSS代码,提高了开发效率。

9.闭包

闭包是什么:内层函数可以调取外层函数的变量称之为闭包

优点:可以重复使用变量,并且不会造成变量污染 。

缺点:会引起内存泄漏

10.cookie, localStorage,sessionStorage 的区别 ?

  • cookie:由服务器端写入的,cookie的存储空间比较小,大概4KB,cookie的生命周期是由服务器端在写入的时候就设置好的,cookie一般用于存储登录验证信息SessionID或者token,
  • localStorage:由前端写入的,生命周期是需要手动清除否则永久保存,存储大小5MB,保存在浏览器中
  • sessionStorage:由前端写入的,生命周期是关闭页面和浏览器之后被清除,仅在当前会话下有效,存储大小5MB,保存在浏览器中

11.防抖和节流

防抖:防抖是指当一个事件触发的时候, 为防止频繁触发事件, 设置定时器,以达到一种 频繁触发期间不处理, 只有当最后一次连续触发结束以后才处理

总结:触发多次事件,只执行最后一次的事件

function debounce(cb,wait){ let timer

return function(){ clearTimeout(timer)

     timer = setTimeout(()=>cb(),wait) }

}

节流:节流是指当一个事件触发的时候,为防止事件的连续频繁触发,设置定时器,达到一种一段时间内只触发一次的效果,在当前事件内不会再次触发,当前事件结束以后,再次触发才有效

总结:点击多次事件,在规定的时间内触发一次一次的触发

function throttle(cb,wait){
  let timeOut
  return function(){
    if(timeOut) return
    timeOut = setTimeout(function(){
      cb()
      clearTimeout(timeOut)
      timeOut = null
    },wait)
  }
}

12.谈一谈垃圾回收机制?

垃圾回收是动态存储管理技术,会自动地释放“垃圾‘’(不再被程序引用的对象),按照特定的垃圾收集算法来实现资源自动回收的功能。
回收的两种机制

  • 1.标记清除(make-and-sweep)
  • 2.引用计数 垃圾回收器会按照固定的时间间隔周期性的执行。

13.元素垂直水平居中有哪些方法

利用定位:父级相对定位,子级绝对定位

  .content{            width:500px;            height:300px;            border:1px solid #0a3b98;            position: relative;        }        .box{            width:100px;            height:40px;            background: #f0a238;            position: absolute;            top:0;            left:0;            right:0;            bottom:0;            margin:auto;        }

定位 + css3位移: 父级相对定位,子级绝对定位,如果top,left是百分比根据父级的宽高来计算的

 .content{            width:500px;            height:300px;            border:1px solid #0a3b98;            position: relative;        }        .box{            width:100px;            height:40px;            background: #f0a238;            position: absolute;            top:50%;            left:50%;            transform: translate(-50%,-50%);        }

弹性盒模型:

 .content{            width:500px;            height:300px;            border:1px solid #0a3b98;            display: flex;            justify-content: center;            align-items: center;        }        .box{            width:100px;            height:40px;            background: #f0a238;        }

网格布局 Grid:

 .content{            width:500px;            height:300px;            border:1px solid #0a3b98;            display: grid;            justify-content: center;            align-items: center;        }        .box{            width:100px;            height:40px;            background: #f0a238;        }

14.页面的布局有哪些方式

1.弹性布局的功能:

  a.屏幕和浏览器窗口大小发生改变也可以灵活调整布局;

  b.可以控制元素在页面上的布局方向;

  c.可以指定如何将垂直于元素布局轴的额外空间分布到该元素的周围;

  b.可以指定伸缩项目沿着主轴或侧轴将伸缩容器额外空间,分配到伸缩项目之前、之后或之间;

2.响应式布局

3.栅格布局

4.瀑布流布局:

   a.有效的降低了界面复杂度,节省了空间:不再需要臃肿复杂的页码导航链接或按钮了。

15.标签 title 和 alt 属性有啥区别

title:title 属性可以用在任何元素上,当用户把鼠标移动到元素上时,就会显示预先设置的 title 的内容,起到对图片说明的作用,实际上就是对图片的解释和备注。

alt:

1.当图片加载不出来的时候,就会在图片未显示的地方出现一段 alt 设置的属性内容

2.浏览器的搜索引擎可以通过 alt 属性的文字描述来获取图片。

16.html5有哪些新特性

1.绘画 canvas;
2.用于媒介回放的 video 和 audio 元素;
3.本地离线存储 localStorage 长期存储数据,浏览器关闭后数据不丢失;
4.sessionStorage 的数据在浏览器关闭后自动删除;
5.语意化更好的内容元素,比如 article、footer、header、nav、p;

17.position的absolut、relative、fixed相对于什么进行定位的?

absolut:相对于最近的父级定位的

relative:相对于自身的正常位置做定位

fixed:相对于浏览器窗口定位的

18.iframe的标签的使用

1.iframe是HTML元素,用于在网页中内嵌另一个网页。

2.iframe默认有一个宽高,存在边界。

3.iframe是一个行内块级元素,可以通过display修改。

iframe常用的元素属性:

  1. src:指定内联网页的地址。
  2. width、height:控制iframe的宽高。
  3. frameborder:iframe默认有个边界,可以设置frameborder为0清除边界。
  4. name:框架的名称。
  5. scrolling:是否可滚动。yes、no、auto。

iframe之间的通信:

  • iframe就是一个隔离沙盒,相当于我们在一个页面内可以操控很多个标签页一样。
  • 浏览器判断你跨没跨域,主要根据两个点:一个是你网页的协议(protocol),另一个就是你的host是否相同(window.location.protocol、window.location.host)。

19.说说你对SPA单页面的理解,它的优缺点分别是什么?

SPA(单页面应用)是指整个应用程序只有一个HTML页面,所有的内容都通过异步加载或动态生成的方式在这个页面中进行展示。SPA通常基于前端框架(如Vue.js、React等)来实现,通过前端路由来控制页面的展示和切换,从而实现快速、流畅的用户体验。

优点:

用户体验好:SPA可以在页面之间快速切换,避免了传统多页面应用的刷新加载,提供了更流畅的用户体验。
前后端分离:SPA采用前后端分离的架构,前端负责页面渲染和交互逻辑,后端负责数据处理和接口提供,使开发更加灵活和高效。
更快的加载速度:SPA在首次加载时会请求较大的JS和CSS文件,但后续页面切换只需要加载数据,因此整体加载速度更快。
代码复用:SPA中的组件化开发使得代码可以更好地复用,减少了重复开发的工作量。
前端路由:SPA采用前端路由管理页面状态,可以实现更灵活的页面切换和导航。

缺点:

首次加载较慢:SPA在首次加载时需要加载较大的JS和CSS文件,可能导致首屏加载时间较长。
SEO不友好:由于SPA只有一个HTML页面,搜索引擎难以获取完整的页面内容,对SEO不太友好。虽然现在搜索引擎对SPA的处理能力有所提升,但仍然存在一定的SEO挑战。
内存占用较高:由于SPA在用户使用过程中始终保持一个页面状态,会占用较多的内存,对于资源有限的设备可能会影响性能。
前进后退问题:SPA的前进后退功能通常需要前端路由的支持,某些情况下可能会导致页面状态出现不一致的问题。

二、vue2

1.vue2的生命周期

 a、beforecreate:创建前,第一个钩子,这个阶段的data,methods,computed以及watch的数据和方法不能被访问。

 b、created: 是实例创建完成后发生的。这个阶段完成数据观测,可以使用数据,更改数据, 无法与Dom进行交互,想要的话可以通过nextTick来访问 ,nexttick延迟回调,更新数据后立即操作dom。

c、beforeMount: 发生在页面渲染之前,当前阶段虚拟Dom已经创建完成,即将开始渲染。 在此时也可以对数据进行更改,不会触发updated。

d、mounted: 在挂载完成后发生,在当前阶段,真实的Dom挂载完毕,数据完成双向绑定, 可以访问到Dom节点,使用$refs属性对Dom进行操作。

e、beforeUpdate: 发生在更新之前,也就是响应式数据发生更新,虚拟dom重新渲染之前被触发, 你可以在当前阶段进行更改数据,不会造成重渲染。

f、updated: 发生在更新完成之后,当前阶段组件Dom已完成更新。 要注意的是避免在此期间更改数据,因为这可能会导致无限循环的更新。

g、beforeDestroy: 发生在实例销毁之前,在当前阶段实例完全可以被使用, 我们可以在这时进行善后收尾工作,比如清除计时器

h、destroyed: 发生在实例销毁之后,这个时候只剩下了dom空壳。组件已被拆解,数据绑定被卸除,监听被移出,子实例也统统被销毁。

2.v-show和v-if的区别?

a、共同点:都是让元素显示和隐藏

b、不同点:

v-if : 通过操控DOM值来实现显示隐藏 (不适合频繁切换. 数据多不建议用if.每一次切换则重新消耗性能.乱)

v-show:通过修改元素的display,实现显示隐藏  (适合频繁切换,在第一次渲染的时候已经消耗了性能)

3. v-if 和v-for的优先级

在vue2中当v-if 与 v-for 一起使用时,v-for 比v-if 优先级高,如果连用的话会把 v-if 给每个元素都添加一下,会造成性能问题 所以不推荐v-if和v-for在同一个标签中同时使用。

原因:先有循环才能渲染

4.组件通信有哪些?

父传子

父组件:通过v-bind绑定属性:需要发送的变量

子组件:子组件通过props接收父组件传过来的属性名

子传父

子组件:在调用子组件的位置 添加自定义事件 使用$emit 发送数据

父组件:可在导入子组件上使用@自定义=变量接收参数

公共传递

1.传递:在父组件内部添加 provide:{命名:'内容'} 并赋明需要具体传递的值

2.接收:在子或者子子 内部 inject:[命名] 接收

3.在相对应页面中可直接获取

5.computed和watch有什么区别?

computed:

1. 支持缓存,只在依赖的数据发生变化时,才会重新计算,否则当多次调用**computed**属性时,调用的其实是缓存;
2. 不支持异步,当**computed**内有异步操作时无效,无法监听数据的变化
3. 如果一个数据需要经过复杂计算就用 **computed**

4. 如果一个属性是由其他属性计算而来的,这个属性依赖其他属性,是一个多对一或者一对一,(某个属性受多个属性影响)

watch:

1. 不支持缓存,每调用一次就计算一次;

2. **watch**支持异步;

3. 如果一个数据需要被监听并且对数据做一些操作就用 watch

4. 当一个属性发生变化时,需要执行对应的操作;一对多(监听多个数据)

6.Vue中的 data 为什么必须是函数

vue组件中data值不能为对象,因为对象是引用类型,每个组件的data都是内存的同一个地址,如果修改一个对象里面的数据,其他的也会被影响到,
data 如果是一个函数,每一个函数都有自己的局部作用域,他改变的话不会影响到其他的数据。

7.Vue中的 key 有什么作用?

列表渲染时的唯一性

页面上标签都对应具体的虚拟dom对象(JS对象),循环中,如果没有唯一的key,页面上删除一条标签,由于不知道删除的是哪一条,需要吧全部的虚拟dom重新渲染,如果知道key,为标签被删除掉,只需要吧渲染的dom为标签删除即可

8.对vuex的理解

1.集中式的存储管理 应用程序中所有组件的状态

2.需要多个组件共享的变量全部存储在一个对象里面 然后,将这个对象放在顶层的vue实例中,让其他组件可以使用

五大核心属性:

1.state  是状态管理器的状态中心,里面是初始化的数据  不可以直接操作Store 中的数据

mutation 同步操作,改变store的数据    变更Store 数据,
2.通过commit 提交方法,this.$store.commit('xxx')

3.action 异步操作,改变store的数据,  让motation中的方法能在异步操作中起作用   
通过store.dispatch 来分发actions 中通过commit提交mutations,进行修改数据

4.getter 是状态管理器中的计算属性  主要用来过滤一些数据,可以在多组件之间复用

5.module  将 store 分割成模块,每个模块都具有state,mutation、action、getter、甚至是嵌套子模块。     

使用场景:登录状态,用户名称,头像,购物车的数量,收藏信息,地理位置。所有需要用户信息的地方验证登陆状态。  

9.谈谈对vue的mvvm的理解

M:(model)对数据修改的业务逻辑

V:(view)视图 前端展示页面

VM:(ViewModel)监听数据变化,同时对视图控制的一个行为

MVVM 模式 采用双向绑定     将Model 的改变实时的反应到View 中,另一方面它实现了DOM监听    
当DOM 发生一些事件(点击 滚动 touch 等)时, 可以监听到,并在需要的情况下改变对应的Data
数据和视图不能直接通信,vm数据发生修改是通知视图进行修改。对视图操作也需要对数据修改,(通过VM实现v和m之间的数据通信。)

10.vue响应式原理

采⽤数据劫持结合发布者-订阅者模式的⽅式,通过**Object.defineProperty()** 来劫持各个属性的**setter, getter** 在数据变动时发布消息给订阅者,触发相应监听回调,,在属性被访问和修改时通知变化

11.虚拟DOM 原理

虚拟dom是对真实dom的抽象,本质是JS对象,这个对象就是更加轻量级的对dom的描述

在渲染页面之前(真实的dom树挂载之前) vue会自己根据真实的dom构建一个虚拟dom,当里面某个节点发生变动时,与旧节点对比一下,发现不一样的地方直接修改在真实对的dom上,就是在虚拟dom上比较新旧节点的同时直接在真实dom上修补

12.$nextTick⽅法有什么作⽤?

$nextTick也叫做异步更新队列方法,而nextTick方法的主要作用就是等待dom元素加载完毕之后才会执行的回调函数,我们经常在nextTick方法里面获取dom元素

13.diff算法

首先,对比节点本身,判断是否为同一节点,如果不为相同节点,则删除该节点重新创建节点进行替换
如果为相同节点,进行 patchVnode,判断如何对该节点的子节点进行处理,先判断一方有子节点一方没有子节点的情况(如果新的 children 没有子节点,将旧的子节点移除)
比较如果都有子节点,则进行 updateChildren,判断如何对这些新老节点的子节点进行操作(diff 核心)。
匹配时,找到相同的子节点,递归比较子节点

14.你都做过哪些 Vue 的性能优化?

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

15.使用过keep-alive吗?

1.keep-alive缓存vue实例,提高性能是 Vue 内置的一个组件,可以使被包含的组件保留状态,避免重新渲染 ,

2.提供 include 和 exclude 属性,两者都支持字符串或正则表达式, include 表示只有名称匹配的组件会被缓存,exclude 表示任何名称匹配的组件都不会被缓存 ,其中 exclude 的优先级比 include 高;

3.对应两个钩子函数 activated 和 deactivated ,当组件被激活时,触发钩子函数 activated,当组件被移除时,触发钩子函数 deactivated。

16.SPA首屏加载速度慢的怎么解决?

首屏时间(First Contentful Paint),指的是浏览器从响应用户输入网址地址,到首屏内容渲染完成的时间,此时整个网页不一定要全部渲染完成,但需要展示当前视窗需要的内容;

加载慢的原因:

  • 网络延时问题
  • 资源文件体积是否过大
  • 资源是否重复发送请求去加载了
  • 加载脚本的时候,渲染内容堵塞了

常见的几种SPA首屏优化方式:

  • 减小入口文件积
  • 静态资源本地缓存
  • UI框架按需加载
  • 图片资源的压缩
  • 组件重复打包
  • 开启GZip压缩
  • 使用SSR

17.vue2中$nextick的用法

延迟操作,将回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它,然后等待 DOM 更新。可以在created中,使用nextick完成操作dom的操作

三、vue3

1. Vue2.0 和 Vue3.0 有什么区别?

响应式的不同:

  • Vue2通过Object.defineProperty对data中的属性进行劫持,当属性值发生变化时,会触发对应的更新函数,从而更新视图。

  • Vue2通过Watcher来实现数据与视图的双向绑定,当数据发生变化时,Watcher会通知对应的视图进行更新。

  • Vue2的响应式原理存在一些缺陷,例如无法监听数组的变化,需要通过特殊的方法来实现.

  • Vue3使用Proxy代替了Object.defineProperty,Proxy可以监听到对象的所有属性,包括新增和删除操作。

  • Vue3使用了WeakMap来存储依赖关系,避免了Vue2中Watcher的内存泄漏问题。

  • Vue3支持了多个根节点的组件,可以更方便地进行组件的复用和组合。

2. vue3带来了什么?

1.更快的渲染速度:Vue3使用了Proxy代理对象,可以更快地跟踪数据变化,从而提高渲染速度。

2.更小的体积:Vue3的体积比Vue2更小,同时也支持按需加载,减少了页面加载时间。

3.更好的TypeScript支持:Vue3对TypeScript的支持更加完善,可以更好地进行类型检查和代码提示。

4.更好的组件封装:Vue3引入了Composition API,可以更好地封装组件逻辑,使得组件更加可复用和易维护。

5.更好的响应式系统:Vue3的响应式系统进行了重构,可以更好地处理嵌套对象和数组的变化,同时也提供了更多的API来处理响应式数据。

总之,Vue3带来了更好的性能、更小的体积、更好的TypeScript支持、更好的组件封装和更好的响应式系统,使得开发者可以更加高效地开发Vue应用。

3.composition API 优势好处特点

优点:

a、composition API是根据逻辑相关性组织代码的,提高可读性和维护性

b、代码量少,更好的重用逻辑代码

c、没有引入新的语法,只是单纯函数

d、异常灵活

e、工具语法提示友好,因为是单纯函数所以很容易实现语法提示、自动补偿

f、更好的Typescript支持

g、在复杂功能组件中可以实现根据特性组织代码,代码内聚性强

h、组件间代码复用

4.vue2和vue3生命周期对比

beforeCreate===>setup()

created=======>setup()

beforeMount ===>onBeforeMount

mounted=======>onMounted

beforeUpdate===>onBeforeUpdate

updated =======>onUpdated

beforeUnmount ==>onBeforeUnmount

unmounted =====>onUnmounted

5.vue2和vue3响应式原理

vue2:

  • 对象类型:通过Object.defineProperty()对属性的读取、修改进行拦截(数据劫持)。

  • 数组类型:通过重写更新数组的一系列方法来实现拦截。(对数组的变更方法进行了包裹)。

存在的问题:

  • 新增属性、删除属性, 界面不会更新。

  • 直接通过下标修改数组, 界面不会自动更新。

vue3:

  • 通过Proxy(代理): 拦截对象中任意属性的变化, 包括:属性值的读写、属性的添加、属性的删除等。

  • 通过Reflect(反射): 对源对象的属性进行操作。

6.vue3响应式数据的判断

isRef: 检查一个值是否为一个 ref 对象

isReactive: 检查一个对象是否是由 reactive 创建的响应式代理

isReadonly: 检查一个对象是否是由 readonly 创建的只读代理

isProxy: 检查一个对象是否是由 reactive 或者 readonly 方法创建的代理

7.reactive和ref有什么区别

从定义数据角度对比:

  • ref用来定义:基本类型数据

  • reactive用来定义:对象(或数组)类型数据

  • 备注:ref也可以用来定义对象(或数组)类型数据, 它内部会自动通过reactive转为代理对象

从原理角度对比:

  • ref通过Object.defineProperty()getset来实现响应式(数据劫持)。

  • reactive通过使用Proxy来实现响应式(数据劫持), 并通过Reflect操作源对象内部的数据。

从使用角度对比:

  • ref定义的数据:操作数据需要.value,读取数据时模板中直接读取不需要.value

  • reactive定义的数据:操作数据与读取数据:均不需要.value

8.谈一谈你对vue3中computed和watch的理解

computed:

1.computed是计算属性,也就是计算值,他更多用于计算值的场景。

2.computed具有缓存性,computed的值在getter执行后是会缓存的,只有在它依赖的属性值改变之后,下一次获取computed的值时才会重新调用对应的getter来计算。

3.computed适用于计算比较消耗性能的计算场景。

watch:

1.watch更多的是“观察”的作用,类似于某些数据的监听回调,用于观察props、$emit或者组件的值,当数据变化时来执行回调进行后续操作。

2.无缓存性,页面重新渲染时值不变化也会执行。

四、uniapp

1.uniapp优缺点

 优点:
    a. 一套代码可以生成多端
    b. 学习成本低,语法是vue的,组件是小程序的
    c. 拓展能力强
    d. 使用HBuilderX开发,支持vue语法
    e. 突破了系统对H5调用原生能力的限制
    缺点:
    a. 问世时间短,很多地方不完善
    b. 社区不大
    c. 官方对问题的反馈不及时
    d. 在Android平台上比微信小程序和iOS差
    e. 文件命名受限

五、git命令

1、 git init 把这个目录变成git可以管理的仓库
2、 git add . 不但可以跟单一文件,也可以跟通配符,更可以跟目录。一个点就把当前目录下所有未追踪的文件全部add了
 3、 git commit -m ‘first commit’把文件提交到仓库
 4、 git remote add origin +//仓库地址 //关联远程仓库 
 5、 git push -u origin master //把本地库的所有内容推送到远程库上

 

六、es6新特性

1.Promise

  • 状态:pending(进行时)、fulfilled(已成功)、rejected(已失败)

  • 用法: Promise 对象是一个同步的构造函数,会接受一个函数作为参数,这个函数的两个参数分别是 resolve和reject

    resolve 函数的作用是将 Promise 对象的状态从 “未完成” 变为 “成功”

    reject 函数的作用是将 Promise 对象的状态从 “未完成” 变为 “失败”

  • 实例方法:

    then() ----异步的, 实例状态发生变化时,触发的回调函数,第一个参数是 resolved状态的回调函数,第二个参数是 rejected 的回调函数(一般使用 catch 方法来替代第二个参数)

    catch() ---- 用于指定发生错误的回调函数

    finally() --- 用于指定 不管 Promise 对象最后状态如何,都会执行的操作

  • 常用的构造函数方法:

    Promise.all() ----将多个 Promise 实例包装成一个新的 Promise 实例

    const p = Promise.all([p1, p2, p3]);
    只有 p1,p2,p3 状态全为 fulfilled ,p 的状态才会变成fulfilled。此时,p1,p2,p3 的返回值组成一个数组,传递给 p 的回调函数。

    只要 p1,p2,p3 有一个状态为 rejected ,那么 p 的状态就变成 rejected。此时第一个被reject的实例的返回值,会传递给p的回调函数。

    Promise.race() ----将多个 Promise 实例包装成一个新的 Promise 实例

    const p = Promise.race([p1, p2, p3]);
    三者谁先改变状态, p 也就会跟着改变状态。率先改变的会将返回值传递给 p 的回调函数。

2.浅拷贝和深拷贝

浅拷贝

1.直接赋值

2.数组的方法:

concat:

  const result = [].concat(arr);
  result[3].name = 'ptu'
  console.log(arr);
  console.log(result);
slice: 
 const result = arr.slice(0)
 result[3].name = 'ptu';
 console.log(arr);
 console.log(result);

  扩展运算符:

const result = [...arr];
result[3].name = 'ptu';
console.log(arr);
console.log(result);

  对象:使用Object.assign(空对象,旧对象):

  const school = {
        name: 'ptu',
        add: ['合肥', '滁州', '芜湖'],
        founder: {
          name: '小宝',
          age: 18
        }
      };
      const result = Object.assign({},school);
      result.add[0] = '安庆';
      console.log(school);
      console.log(result);
深拷贝

1.JSON:先用 JSON.stringify 将对象转为字符串,再使用 JSON.parse 将字符串转为一个新对象

2.缺点就是不能复制方法

3.集合Set

Setes6新增的数据结构,类似于数组,但是成员的值都是唯一的,没有重复的值,我们一般称为集合

  • 方法:add()、delete()、has()、clear() 、size()  

  • // 声明集合 自动去重
        const s = new Set([1,2,3,41,12,21,1,1,1,2,3,4])
        console.log(s); //[1,2,3,41,12,21,4]
        // 1.元素个数
        console.log(s.size); //7
        // 2.添加
        s.add(8)
        // 3.删除
        s.delete(1)
        console.log(s);//[2,3,41,12,21,4,8]
        // 4.检测是否包含某个元素
        console.log(s.has(2)); //true
        // 5.清空
        // s.clear()
        console.log(s); //[]
    应用场景: 数组去重、求交、并、差集。
     

3.字典Map

Map类型是键值对的有序列表,而键和值都可以是任意类型

  • 属性和方法:size()、set()、get()、has()、delete()、clear()

  • // 声明Map
            let m = new Map()

            // 1.添加元素(键值对)
            m.set('name','小宝')
            m.set('age',18)

            // 2.获取元素
            console.log(m.get(name)) //小宝

            // 3.删除元素
            m.delete('name')

            // 4.获取元素个数
            let size = m.size
            console.log(size) //1

            // 5.检测是否包含某个元素
            console.log(m.has('age')); //true
            
            // 6.清空Map
            m.clear()
            console.log(m) //0
     

4.数组去重

1.Array.from(new Set(arr)) 方法从一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例。

2.[...new Set(arr)]

5.forEach、for in、for of的区别,哪些是可以使用break、continue的

forEach是用来循环数组的,没有返回值,可以直接修改数组中的某一项

for in 是用来遍历对象属性的,可以使用break、continue进行中断或者继续的

for of 可以遍历数组、对象、字符串等,可以使用break、continue进行中断或者继续的

6、大文件上传慢如何解决

分片上传:分片上传 (Chunked Upload) 是将文件分成若干个小块(通常是几MB大小),然后将每一块单独上传。这样,当网络状态较差时,只会有一小部分的数据受到影响,而不是整个文件上传失败。分片上传还可以让服务器端并行处理多个分片,提高上传速度。

将文件进行切割

async uploadFile (file) {
    // file 获取当前上传的视频文件
    let that = this
    const CHUNK_SIZE = 1024 * 1024 * 20 // 每个块的大小为20MB
    const chunks = Math.ceil(file.size / CHUNK_SIZE) // 计算文件分成多少块 总块数
    let uploadedChunks = 0 // 已上传的块数
    let uploadedBytes = 0 // 已上传的字节数
    let progress = 0 // 上传进度

    for (let i = 0; i < chunks; i++) {
        const start = i * CHUNK_SIZE // 每块的起始位置
        const end = Math.min(start + CHUNK_SIZE, file.size) //  // 每块的末尾
        const chunk = file.slice(start, end) // 将文件在指定的位置进行切割
        const res = await that.uploadChunk(chunk, i, chunks, file.name) // 将每个模块执行上传方法
        uploadedChunks++
        uploadedBytes += end - start
        progress = Math.floor(uploadedBytes / file.size * 20)
    }
},

上传切片

uploadChunk (chunk, index, totalChunks, fileName) {
    let that = this
    // 将chunk片段转换为File文件格式
    let newChunk = new File([chunk], "分片文件", { type: "*", lastModified: Date.now() })
    const formData = new FormData()
    // 根据后端的需要,传参,文件上传传参:formData
    formData.append('dir', 'cs')
    formData.append('file', newChunk)
    formData.append('blob_index', index)
    formData.append('total_blob', totalChunks)
    formData.append('file_name', fileName)
    
    return axios.post(url, formData, {
        headers: {
          'Content-Type': 'multipart/form-data'        // 文件上传格式
        }
      }).then(res => {
        // 上传成功的处理
      }).catch(err => {
        console.log(err)
      })
    }

七、高德地图

呼吸灯Api:ScatterLayer

  • 10
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值