signed

QiShunwang

“诚信为本、客户至上”

面试题All

2021/6/3 13:32:02   来源:

1.html

HTML1.HTML文件中的DOCYPE作用

文档类型  :告诉浏览器当前文件是用什么版本写的
<!DOCYPE html>  =>html5版本写的

HTML2.HTML、XML、XHTML


三者都是标记语言
HTML 超文本标记语言
超文本:可以包括图片文字链接视频音频登元素
通常说的HTML,就是HTML4

发展:
HTML4 先用,实现结构,再制定标准(不严谨,兼容不好,语法不规范)
  |
 XML  可扩展标记语言  自定义任意标签,只能有一个根标签 <root></root>,严格区分大小写  (太严格)
  |
XHTML 可扩展超文本标记语言  W3C 万维网联盟出的  太严格 浏览器解析不方便
  |
 HTML5 超文本标记语言  目前标准,就是一种语法标准,规定浏览器应该如何解析标签,html5就是版本号
 
 

HTML3. HTML 与HTML5区别

HTML4HTML)与HTML5区分
 HTML4的声明很长
 HTML4没有结构语义化标签 比如 aside...

HTML4.HTML语义化理解

1.利于SEO(搜索引擎优化 Search Engine Optimization),可阅读性更好
2.页面内容结构化,使结构更清晰

HTML5.有利于SEO

title
Meta 标签 keywords
Description 
img标签加 alt属性 图片损坏不能显示时出现 替换文本
         (title 鼠标移上去,提示信息,这是什么图片)
同一个页面不要出现两次以上的h1.h2 h3
关键字放在页面首尾

HTML6.锚点定位

当我们点击链接时,可以快速定位到页面的某个位置
//第一种:
1.href属性,设置属性值为#名字形式
2.找到目标位置标签,标签里面添加一个id属性=刚才的名字
<a href="#two"> 第二部</a>
<h3 id="two">第二部标题</h3>

//第二种:
<a href="#two"> 第二部</a>

前面加<a name="two"></a>   name只能给a标签设置
<h3>第二部标题</h3>

//第三种
先找到其他页面紧跟着#名字
<a href="#two"> 第二部</a>
<a href="index.html#two"></a>

HTML7.H5新增特性

//1.语义化标签...........................................................................  
article 正文内容
header 头部
footer 底部
section 块、区域
aside 侧边栏
nav 导航栏dat
main 主体
//2.自定义属性  data-xxx....................................................................
自定义属性:给html 元素添加额外的数据信息的方式
data-num="123"
比如,做删除的话 根据id找到这一项进行删除   data-id="101"  通过dataset就可以拿到自定义属性  dataset.id
动态渲染出来的结构,我要按删除按钮删除,给删除按钮的父元素注册事件委托
删除按钮上绑定自定义属性 data-id="下标"  attr(xxx) 获取属性值,从而删除
 jquery 中 prop 操作标准属性的值 (checked selected disabled)
//3.input的类型值 type属性值.............................................................
 date  可以选择日期,已经美观很多了,还存在兼容问题,谷歌是可以的 ,ie好像不行
 url email 自带表单校验
 还有很多 查
 //4.全域属性............................................................................
 conenteditable 让内容可编辑 比如p标签上加上这个属性,就可以编辑了
 hidden 隐藏域
 draggable 可拖拽 用的话必须写全draggable="true" 一般拖拽图片  
 结合拖拽api 可以实现文件上传等  dragstart事件  drop
 //5.视频、音频、画布......................................................................
 video audio canvas
 (兼容性 video.js autoplay属性自动播放)  echarts (canvas)

//6.script 标签  defer async   提升网页性能................................................
<script src="example.js"></script> 
浏览器立即加载并执行相关脚本,不等待后续加载的文档元素,读到就开始加载和执行,会阻塞后续文档加载

<script async src="example.js"></script> 
异步执行,后续文档加载与js脚本脚本加载执行是并行的

<script defer src="example.js"></script>
异步执行,后续文档加载与js脚本加载并行,但js脚本仅加载不执行,等文档所有元素解析完,才执行

//7.本地存储 localStorage SessionStorage 
localStorage 长期存储  浏览器关闭后数据不丢失
SessionStorage 短期存储  浏览器关闭后数据会丢失

//8.websocket 双向实时通信协议(即时通讯)(性能好)
//回答这个即可:
聊天界面 聊天机器人  一般用 Soket-io 库  原生语法,可以查到 
http协议 网络通信协议的基石,但只能做到客户端请求服务器,服务器做出响应,做不到让服务器主动给客户端推送消息

.............................................................................................
下面了解
websocket技术
    http只能由客户端发起请求,WebSocket是一种双向的数据通信协议,客户端可以给服务器发信息,服务器也可以给客户端发信息
 原生:创建websocket实例 ws = new WebSocket('服务器地址')
		 监听是否连接成功  onopen 
		 客户端发送消息给服务端 ws.send('xxx')
		 接收服务端的消息 ws.onmessage = f  
		 断开 ws.close()
		 监听端口 ws.onclose = fn
封装好的socket.io 
- 安装包 socket.io-client 导入使用 `import io from 'socket.io-client'`
- 建立连接 `const socket = io('地址',{额外传参})` 等同于 原生websocket new WebSocket()
- 监听连接状态 `socket.on('connect',  () => { .... })`
- 发消息:`socket.emit('自定义消息名', '内容');`
- 收消息:`socket.on('自定义消息名', function(msg){}`
- 关闭链接:`socket.close()`

HTML8.LocalStorage、SessionStorage、cookie区别

本地存储
//1、
localStorage(5M) 生命周期是永久  浏览器关闭后数据不丢失,除非手动清除
SessionStorage(5M) 生命周期为当前窗口或标签页   当前窗口或标签页、浏览器关闭后数据会丢失
//2、
localStorage 容量大(5M) 只存储数据在本地,不会主动提供数据,要拿自己去手动拿
cookie 容量小(4K)
      安全性不高 cRfs攻击
      在http请求中携带数据在浏览器和服务器之间来回传递,消耗性能
      有些移动端设备会禁用cookie
      只是会在设置的cookie过期时间之前有效,即使关闭浏览器

//3.不同浏览器无法共享localStorage或sessionStorage中的信息

相同浏览器的不同页面间可以共享相同的 localStorage(页面属于相同域名和端口)

但是不同页面或标签页间无法共享sessionStorage的信息。
这里需要注意的是,页面及标签页仅指顶级窗口,如果一个标签页包含多个iframe标签且他们属于同源页面,那么他们之间是可以共享sessionStorage的。

cRfs攻击:跨站请求伪造 攻击者盗用了你的身份,以你的名义发送恶意请求
//4.一般移动端做本地存储用localStorage
//   PC端 用cookie


其他存储方式
webSQL  sql语句
INdexedDB >=250MB甚至没有上限

HTML.9块级元素&&行内元素

//1.行内 块级元素
行内 :  a span b img input (表单元素) em i strong 与文字有关的
块级: div  p h1-h6 dl dt dd tabel form  tr
块级元素独占一行,   块级元素可以直接设置宽高,                     默认宽度为父级的百分百,可以放行内和块级元素  设置内外边距 

行内元素可以一行多个,行内元素设置宽高无效,需要设置宽高转成行内块,默认宽度由内容决定 只能行内/文本 无内外边距
//2.引申问题:css元素显示模式
display: block
         inline
         inline-block
行内块:
块和行内的特点
和相邻的行内元素在一行上,一行显示多个,但有空白间隙
可以设置宽高,内外边距
默认宽度是它本身内容的宽度
可以放任意标签

行内块间隙解决:删除换行 结构不清晰
               浮动

行内/行内块水平居中:给父盒子添加 text-align:center

HTML.10label标签

//for属性规定label与哪个表单元素绑定 
扩大用户的点击范围
方法一:
<label for="sex"> <img src="1.ipg"/></label>
<input type="radio" name="sex" id="sex" />
核心:for与id属性值相同
方法二:
<label>
    <input type="radio" name="sex" />
     <img src="1.ipg"/></label>


HTML.11img标签alt title

img标签加 alt属性 图片损坏不能显示时出现 替换文本
          title 鼠标移上去,提示信息,这是什么图片

HTML.12 img标签srcset属性

//作用:做响应式图片
srcset 额外的图片集合 ,浏览器根据屏幕状态,争对不同dpr(设备像素比)选择合适的图片显示  
w 描述符
sizes属性 两个值 分别是媒体查询的条件 图片对应的尺寸
<img srcset="320.png 320w,
             640.png 640w"
    sizes="(max-width:320px) 320px"
    src="640.png"
>

HTML.13picture标签

Picture 标签(图像容器)  换图
picture标签包裹在img外面,最终会将匹配到的图片路劲,使用显示

<picture>
   <source screen="640.png" media="(min-width:640px)">
   <source screen="480.png media="(min-width:480px)">
   //默认
   <img src="320.png" alt="">
</picture>

HTML.14meta标签有哪些常用方法

1.设置网页关键词(SEO<meta name="keywords" content="电商 价值"/>
2.网页视口 viewpoint 移动端开发
<meta name="viewpoint" content="width=device-width,inital-scale=1,user-scalable=no"/>
                      视口宽度等于设备宽度    视口缩放比11    禁止用户用手指进行缩放
3.设置字符集
<meta charset="utf-8" /> 万国码

2.css

CSS1.css优先级

!important>行内样式>id选择器>/属性/伪类选择器>伪元素/标签选择器>通配符选择器*>继承
无穷大       1000    100         10               1               0           0
下面的css权重,会高于上面的css权重
权重:4位数 无进位 
a:hover  0,0,0,1+0,0,1,0=>0,0,1,1

css2.px em rem 适配、媒体查询

 px是固定单位,  
    em是相对单位,相当于当前文字的大小,如果没有就找父元素的font-size
    rem也是相对单位,相对于html的fontsize的大小
rem 一般可以用来做rem适配
rem适配原理:
1.使用rem做单位 插件转换,直接写px即可
width:10rem
2.动态的设置不同屏幕下的HTML的font-size大小
375px html{font-size:37.5px} 

rem+媒体查询 断档式适配
rem+flexsible.js 开发中常用     线性适配
vw vh


媒体查询
响应式适配:根据不同的屏幕尺寸,显示不同的效果
不会增加权重,一般放在下面
@media screen and (min-width:1200px){
    .box{
        width:1000px;
    }
}

css3.设置比12px还小的字体

  p {
    	font-size:12px;
			-webkit-transform:scale(0.8);
    	}

css4.css写一个三角形

 div {
      width: 0;
      height: 0;
      border: 20px solid transparent;
      border-width: 40px 20px 0 0;
      border-right-color: #f99;
    }

css5.盒子模型

标准盒子模型
宽度width=内容content+border+padding+margin撑大盒子
C3怪异盒模型(IE盒模型)
box-sizing:border-boxcheng
宽度width=width(content+border+padding)+margin在盒子里面不会撑大盒子

css6.不定宽高的div水平垂直居中

1、父元素添加 position: relative
		div{
			position:absolute;
			top: 50%;
             left: 50%;
             transform: translate(-50%, -50%);
		}
	2、div {
	   display: flex;
       justify-content:center; //子元素水平居中
       align-items:center; //子元素垂直居中
	 }
      
    3、#box {
        width: 100px;
        height: 100px;
        position: relative;
    }

    #content {
        width: 50px;
        height: 50px;
        position: absolute;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        margin: auto;
    }

css7.盒子水平居中

1.margin : 0 auto
2.子绝父相 子元素 left:50%   transform:translateX(-50%)
3.子元素转行内块 父盒子加text-align:center
4,flex布局
父级:diaplay:flex
justify-content:center
align-items:center

css8.flex常用属性

1. flex-direction: 设置容器中的主轴方向 row(默认) column、
水平向右 垂直向下

场景: 上下布局
改变主轴方向 
display:flex
flex-direction:column
justify-content:space-between


2. flex-wrap: 项目在主轴方向上是否换行显示  no-wrap默认不换行 wrap 换行
默认不换行,内容装不下才会换行,缩小比例展示

3. justify-content: 设置容器中的项目在主轴上的对齐方式
flex-start 起点对齐
flex-end 终点对齐
center 居中
space-around 环绕 1 2 2 1
space-between 两端对齐
space-evenly 均衡分布 1 1 1 1


4. align-items: 单行项目在侧轴上的排列方式
flex-start 起点对齐
flex-end 终点对齐
center 居中
Stretch 拉伸 默认值 不设高,会拉伸,撑满

5. align-content: 多行项目侧轴上的对齐方式
flex-start 起点对齐
flex-end 终点对齐
center 居中
Stretch 拉伸 默认值 不设高,会拉伸,撑满

(多行多两个)
space-around 环绕 1 2 2 1
space-between 两端对齐

6. flex-flow: 是flex-direction和flex-wrap的合写, 默认值为row nowrap

7.flex:1 把剩余空间沾满
flex:父容器在主轴方向上的可用空间
剩余空间=父元素宽度-所有子元素宽度之和

css9.布局场景

//1.双飞翼布局 左右固定,中间随意拉伸
第一种:flex布局
dispaly:flex
左 固定px 右 固定px  中间 flex:1

第二种:浮动
左 float:left   右 float:right
中间盒子:overflow:hidden
注:left right 结构必须在center前

第三种:定位
左右绝对定位占到两边
设置父盒子  左右padding左右的宽度
padding :0 20px;

//2.两栏布局,左定,里内容居中 右边自适应,右边类似购物车一样的东西,可以随意添加删除
大盒子:display:flex
左定宽  右flex:1
内容:
justify-content:center; //子元素水平居中
 align-items:center; //子元素垂直居中

//3.首尾固定,中间随意拉伸
第一种:flex布局
dispaly:flex
头 固定px 尾固定px  中间 flex:1

第二种:定位 
头尾固定定位
padding-top :头高度
padding-bottom : 尾高度
中:vh (视口高度)  1vh=视口高度的1/100
用css3新增的calc()函数(可以动态设置border margin padding font-size 和width height)
height=calc(100vh-头高-尾高)
overfolw:scroll  滚动条 

calc()函数 用来计算长度的表达式 + - * / 运算符两侧必须有空格

第三种:
头尾绝对定位
top:0
bottom:0
宽自适应  高写死


css10.定位

position 
static(默认 静态定位 不定位)
固定 fixed  参照物:整个浏览器              脱标
绝对 absolute 参照物:最近一级父(祖先)元素  脱标
相对 relative                              不脱标
 
粘性定位 sticky   (吸顶效果)  滑动
               position:sticky
               top:0  10px
               设置盒子,距离浏览器顶部边缘多少距离的话开始吸顶

css11.z-index

元素层叠
有定位的元素,加z-index才有效果
值越大,层级越高 
css下面层级比上面高

坑:如果父元素有定位且配置了z-index 优先按照父元素定位的z-index进行层级比较

css12.清除浮动

清除浮动造成的影响,浮动脱标,不占位置(父盒子不会被撑开)

1.定高法(父元素写死一个高) 子盒子变 高度写死了
2.在浮动元素末尾添加一个子盒子 设置clear:both
3.父元素添加overflow:hidden 触发BFC
4.after伪元素清除 
.clearfix::after{
content:''
height:0
display:block
clear:both
}
5.双伪元素清除

//兼容ie
.clearfix{
zoom:1
}

css13.BFC

块级格式上下文
是一块独立的渲染区域
触发了BFC,这块区域就是一块独立的渲染区域
会将处于BFC的内容和处于BFC外的内容隔离

BFC应用:
1.处理会计期元素上下margin合并
2.处理margin塌陷
3.清除浮动
4.实现自适应布局

触发BFC方式:
1.position:absolute/fixed
2.float:left/right
浮动元素多个放在一起,会互相隔开
3.overflow:非visible
hidden /auto/scroll
4.display:inline-block

css14伪元素/伪类区别

伪类:  以:前缀,可以添加到一个选择器的末尾
选中页面中存在的真实元素 
:hover 鼠标悬停
:nth-child(1) 兄弟元素的第一个
:checked 所有选中状态
选择器权重与类选择器权重一样高
用于让样式在元素特定状态下才被应用到实际元素身上

伪元素:
:before :after
创建元素,不在dom树上的元素
伪元素无法注册事件,所以不要通过js来操作它

css15.重绘和重排(回流)

重排(回流)
元素的几何属性,比如宽高,对布局造成改变的,就会进行重新计算,更新布局
重排就会触发重绘

重绘
改变了不影响布局的样式,颜色,背景色,触发重绘
重绘不会导致重排

优化页面渲染性能:尽量减少重绘和重排的次数
方法:1.集中修改样式(一次重排重绘)
     2.利用 transform 实现动画变化效果, 去代替 left top 的变换
     
          transform变换, 只是视觉效果! 不会影响到其他盒子,  只触发了自己的重绘
    3. 使用文档碎片(DocumentFragment)可以用于批量处理, 创建元素

           文档碎片的理解:
           documentFragment是一个保存多个元素的容器对象(保存在内存)当更新其中的一个或者多个元素时,页面不会更新。当documentFragment容器中保存的所有元素操作完毕了,  只有将其插入到页面中才会更新页面。
      


css16.精灵图

Sprites 
把网站用到的一些图片整合到一张单独的图片中
使用:background :url  background-position(0 -200px)
优点:减少网页的http请求,加快网页的加载速度
缺点:测量、使用维护麻烦,新增/换图标   不能随意改大小,放大失真

后续:字体图标(特殊的图标,像文字一样,改大小颜色) iconfont.cn
      svg矢量图标

css17.动画

//1.动画:
1.声明动画 
@keyframs 自定义动画名称{
0%{
css代码
}

}
四组动画,五个点
2.使用动画
 animation:go 2s;
 
 //2.动画8大属性
动画名称
持续时间(第一个出现的时间)
延迟时间
速率曲线 linear 匀速
steps(步数)分多少步完成  时钟
执行次数  infinite 无限次
正逆序播放 alternate  交替执行
执行状态  running 默认   paused暂停
运行结束状态 forwords最后一帧 (留在最后状态)
           backwords第一帧
//3.动画对比过度
    过度:一个元素从A状态转换到B状态的过程
    特点:有且仅有两个状态的切换
          无法主动触发
          执行次数有限制
          过度添加A状态 执行两次 A-B B-A
          过度添加B状态(HOVER) 执行一次 A-B 瞬间到A
    动画:
    实现多个状态切换
    可以主动执行
    执行次数可控
    
    能用过度解决用过度,否则动画

css18.2D转换transform

平移  translateX translateY translate(x,y) px %
缩放 scale(倍数) 小数缩小  整数放大
原点 origin  谁发生变化,转换原点就加给谁
旋转 rotate(deg) 旋转改变坐标系
斜切 skew(deg) 斜切那个轴,那个轴保持不动,另一根轴倾斜相应角度
场景:平行四边形菱形

转换合写:
当出现多个2d转换需要连写
元素发生 旋转改变坐标系
所有2d转换理解为转换至 (多个状态下面有2d效果,需要复制前面已经存在的transform效果)

css19.元素隐藏

display:none 盒子不占位置  继承性(子元素也会有)重排和重绘
visibility:hidden 盒子占位置 ,重绘
opacity:0 透明度为0 盒子占位置
transform:scale(0,0) 只是视觉效果变换,不会影响其他盒子布局
 

css20.垂直居中img/表格

img的容器设置

display:table-cell
text-align:center
vertical-align:center

表格中文字居中对齐
display:table-cell
vertical-align:center

css21.图片懒加载

img 设置 data-set属性 不是src,不会发送http请求 动态控制将data-set属性替换成src属性即可

css22.外边距塌陷

外边距塌陷
1.相邻块元素垂直排列,会出现外边距的合并,当两个块级元素同时设置margin值
上面margin-bottom
下面 margin-top
会重叠
解决:两个外边距不要同时出现

2.嵌套元素,子盒子margin-top,父盒子和子盒子一起往下
解决:父盒子 overflow:hidden
     父盒子fixed
     父盒子上边框(设置透明)
     父盒子设置padding值

css23.外边距合并

相邻块元素垂直排列,会出现外边距的合并,当两个块级元素同时设置margin值
上面margin-bottom
下面 margin-top
取两者的最大的值uu

水平margin永远不会重合


一个继承宽度的盒子,加margin padding都不会撑大盒子,会收缩

css24.常见布局方式

静态布局  
最传统的布局方式,网页中所有尺寸都是由px作为单位,设置了min-width,如果宽度小于就会出现滚动条,如果大于这个宽度则内容居中外加背景。

自适应布局
自适应布局是为不同的屏幕分辨率分别定义不同的布局。
左固 右自
左自 右固
左右固定 中自
等分布局: footer大盒子 五等份
    footer{
         position:fixed
         width:100%;
         bottom:0
         height:~px
      }
   body{
     padding-bottom:~px
    }
  ul{
    display:flex
       li{
          width:20%
          flex:1
         }
     }

流式布局( 百分比布局 %)
宽度自适应,使用%百分比定义宽度,高度写死

响应式布局:媒体查询

弹性布局 (rem/em flex布局)

css25.less sass scss

                    插件
less css的超集 less------>css,页面引入css
新增嵌套 变量 混入 选择器继承
变量   @color:lime
原样输出 ~'/'
混入
.w{}  调用 .box{.w}
.w(){}(有参)  调用 .box{.w()}
嵌套 在选择器里面嵌套其他的选择器
后代写在{}里
子代>
并集,
交集伪类 &代表自己
//使用
安装依赖 yarn less less-loader -D
<style lang='less'></style>

//.........................................................................
scss是SASS的新语法,是c3语法的超集,新增嵌套 变量 混合 选择器继承
变量: $变量名=值
安装依赖 css-loader node-loader   sass-loader -D
<style lang='scss'></style>

css26.Bootstrap

快速实现布局的ui框架

删格系统:将盒子分成12列,看当前盒子在不同屏幕上占多少列
col-lg-xx  大屏占多少列
col-md-xx   中
col-sm-xx   小
col-xs-xx   超小
不管有多少个盒子,准备此屏幕一份放多少个n,一个盒子在相应的屏幕里就有12/n列
需求:6个盒子
大屏  一行 34
中    一行34
小    一行26
超小  一行112

css27.css3新增

1. 圆角 border-radius
2. 盒子模型 box-sizing
3. 阴影 box-shadow 盒子阴影  text-shadow 文字阴影
4. 过渡 transition
5. 2D转换transform  translate(平移) scale(缩放)  skew(斜切) rotate(旋转) transform-origin 控制转换中心点
6. 3D转换 perspective(透视距)  transform-style(3D控件效果)
7. 渐变 linear-gradient(线性) radial-gradient(径向)
8. 弹性布局 flex
9. 媒体查询 @media screen and () {...}
10. 边框图片 border-image
11. 自定义动画 @keyframes    animation
12. 颜色 新增RGBA HSLA模式
13. 背景 background-size   background-origin   background-clip

3.js

js的数据类型有哪些

答: 简单数据类型: number string boolean undefined   null
	复制数据类型: object  function  array

typeof返回的数据类型

答: number string boolean undefined  object  function 
   特殊情况:
   typeof null -->object
   typeof array -->object
   typeof typeof 任何类型  -->string

返回false的情况有哪些

答: 0  ""   null  false  NaN  undefined  不成立的表

什么是深拷贝什么是浅拷贝

答: 浅拷贝: 拷贝对象的一层属性,如果对象里面还有对象,拷贝的是地址, 两者之间修改会有影响,适用于对象里面属性的值是简单数据类型的.
    深拷贝: 拷贝对象的多层属性,如果对象里面还有对象,会继续拷贝,使用递归去实现.

如何实现深拷贝和浅拷贝

:
浅拷贝:
    var obj = {
      class: 'UI',
      age: 20,
      love: 'eat'
    }
    function getObj(obj) {
      var newObj = {}
      for (var k in obj) {
        newObj[k] = obj[k]
      }
      return newObj
    }
    var obj2 = getObj(obj)
    console.log(obj2)

深拷贝: 
		var obj = {
      class: '前端',
      age: 26,
      love: {
      friuts : 'apple',
      meat: 'beef'
      }
    }
		function getObj(obj) {
      var newObj = {}
      for (var k in obj) {
        /* if (typeof obj[k] == 'object') {
          newObj[k] = getObj(obj[k])
        } else {
          newObj[k] = obj[k]
        } */
        newObj[k] = typeof obj[k] == 'object' ? getObj(obj[k]) : obj[k]
      }
      return newObj
    }
    var obj2 = getObj(obj)
    console.log(obj2)

对闭包的理解?并能举出闭包的例子

: 闭包 函数和声明该函数的词法环境的组合(两个嵌套关系的函数,内部函数可以访问外部函数定义的变量)
    闭包的优点:1、形成私有空间,避免全局变量的污染
               2、持久化内存,保存数据
    闭包的缺点:1、持久化内存,导致内存泄露
    解决:1、尽快避免函数的嵌套,以及变量的引用
         2、执行完的变量,可以赋值null,让垃圾回收机制,进行回收释放内存(当不在引用的变量、对象,垃圾回收机制就会回收)
     垃圾回收机制:常见的浏览器垃圾回收算法: 引用计数 和 标记清除法
     			1)引用计数:如果没有任何变量指向它了,说明该对象已经不再需要了。缺点:循环引用
                2)标记清除法:在JS中就是全局出发定时扫描内存中的对象,无法触及的对象,就会背回收。
例: 点击li获取当前下标
    <ul>
      <li>111</li>
      <li>222</li>
      <li>333</li>
      <li>444</li>
      <li>555</li>
    </ul>
      var lis = document.querySelectorAll('li')
      for (var i = 0; i < lis.length; i++) {
        (function (j) {
          lis[j].onclick = function () {
            console.log(j)
          }
        })(i)
      }

什么是原型和原型链

答: 原型: 函数都有prototype属性,这个属性的值是个对象,称之为原型
   原型链: 对象都有__proto__属性,这个属性指向它的原型对象,原型对象也是对象,也有__proto__属性,指向原型对象的原型对象,这样一层一层形成的链式结构称为原型链.

call、apply和bind的区别

: 1. call和apply方法都可以调用函数,方法内的第一个参数可以修改this的指向
	2. call方法可以有多个参数,除了第一个参数,其他参数作为实参传递给函数
		 apply方法最多有2个参数,第二个参数是个数组或伪数组,数组里面的每一项作为实参传递给函数
	3. bind方法不能调用函数,它会创建一个副本函数,并且绑定新函数的this指向bind返回的新的函数

=的区别

答:== 表示是相等,只比较内容
   === 表示是全等,不仅比较内容,也比较类型

es6-es10新增常用方法

: 
es6:
1letconst
2、解构赋值  let { a, b } = { a: 1, b: 2 }
3、箭头函数
4、字符串模板
5、扩展运算符
6、数组方法:map、filter等等
7、类:class关键字
8、promise
9、函数参数默认值 fn(a = 1) {}
10、对象属性简写 let a = 1; let obj = {a}
11、模块化:import--引入、exprot default--导出

es7:
1、includes()方法,用来判断一个数组是否包含一个指定的值,根据情况,如果包含则返回true,否则返回false。

es8:
1、async/await

es9:
1、Promise.finally() 允许你指定最终的逻辑

es10:
1、数组Array的flat()和flatmap()
   flat:方法最基本的作用就是数组降维
      var arr1 = [1, 2, [3, 4]];
            arr1.flat(); 
            // [1, 2, 3, 4]

        var arr3 = [1, 2, [3, 4, [5, 6]]];
        arr3.flat(2);
        // [1, 2, 3, 4, 5, 6]

        //使用 Infinity 作为深度,展开任意深度的嵌套数组
        arr3.flat(Infinity); 
        // [1, 2, 3, 4, 5, 6]
   flatmap:方法首先使用映射函数映射(遍历)每个元素,然后将结果压缩成一个新数组

怎么理解函数的防抖和节流

:
1、定义:
防抖: 就是指触发事件后在n秒内函数只能执行一次,如果在n秒内又触发了事件,则会重新计算函数执行时间。
     例如:设定1000毫秒执行,当你触发事件了,他会1000毫秒后执行,但是在还剩500毫秒的时候你又触发了事件,那就会重新开始1000毫秒之后再执行

节流: 就是指连续触发事件但是在设定的一段时间内中只执行一次函数。
     例如:设定1000毫秒执行,那你在1000毫秒触发在多次,也只在1000毫秒后执行一次
     
2、防抖和节流的实现:
    <body>
    <input type="text" class="ipt" />
    <script>
      var timerId = null
      document.querySelector('.ipt').onkeyup = function () {
        // 防抖
        if (timerId !== null) {
          clearTimeout(timerId)
        }
        timerId = setTimeout(() => {
          console.log('我是防抖')
        }, 1000)
      }

      document.querySelector('.ipt').onkeyup = function () {
        // 节流
        console.log(2)
        if (timerId !== null) {
          return
        }

        timerId = setTimeout(() => {
          console.log('我是节流')
          timerId = null
        }, 1000)
      }

    </script>
  </body>

什么是事件流

答: 事件流是指事件传播的顺序,由事件捕获 => 目标事件 => 事件冒泡

如何阻止冒泡和默认行为

: 阻止冒泡和捕获  e.stopPropagation()
    阻止默认行为   e.preventDefault()   return false
    注意:addEventListener注册的事件,在高浏览器版本中,return false将没有效果,必须要用事件对象

原生注册事件的方式有哪些?区别是什么

: 注册方式
事件三要素:事件源 事件名  事件处理函数 
 mouseenter 鼠标进入事件    mouseleaver 鼠标移除事件 
 keydown 键盘按下时触发   keyup  键盘抬起时触发  keypress 键盘按下时触发
		  1. on + 事件名称 click   
		  2. addEventListener
		区别: 
			1. 使用on注册事件,同一个元素只能注册一个同类型事件,否则会覆盖。
			2. addEventListener可以注册同一事件多次,不会被覆盖。


.元素.on+'事件名'=null 移除事件
元素.removeEventListener(''事件名',事件处理函数,false)  移除事件

http和https的区别

答:
  1.https协议需要到CA申请证书,一般免费证书较少,因而需要一定费用。
  2.http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl/tls加密传输协议。
  3.http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
  4.http的连接很简单,是无状态的;HTTPS协议是由SSL/TLS+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。

get 和post的区别

答: get
			1. 在url后面拼接参数,只能以文本的形式传递数据
			2. 传递的数据量小,4KB左右
			3. 安全性低, 会将数据显示在地址栏
			4. 速度快,通常用于安全性要求不高的请求
			5. 会缓存数据
	post
		    1. 安全性比较高
			2. 传递数据量大,请求对数据长度没有要求
			3. 请求不会被缓存,也不会保留在浏览器历史记录里

项目中遇到的状态码有哪些

答: 200  请求成功,  2开头的异步表示请求成功
		304  请求被允许,但请求内容没有改变, 3开头的一般请求完成
		400  请求格式错误,  4开头的一般表示请求错误
		404  请求的资源(网页)不存在,  
		500  内部服务器错误,  5开头的一般都是指服务器错误

jsonp的原理?以及优缺点

答: 原理: 利用script标签的src属性具有天然可跨域的特性,由服务端返回一个预先定义好的Javascript函数的调用,并且将服务器数据以该函数参数的形式响应给浏览器.
		优点: 完美解决在测试或者开发中获取不同域下的数据,用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了。
		缺点:Jsonp只支持get请求而不支持post 请求,也即是说如果想传给后台一个json 格式的数据,此时问题就来了, 浏览器会报一个http状态码41错误,告诉你请求格式不正确.

什么是同源策略?怎么解决跨域问题

答: 同源策略: 同源策略是浏览器的一种安全策略, 所谓同源是指域名、协议、端口完全相同,不同源则跨域。
   解决跨域的方法: 
			1. 通过jsonp跨域
			2. 跨域资源共享(CORS  Access-Control-Allow-Origin: http://api.bob.com)
			3. nginx代理跨域

页面通信的方式有哪些

答: 1. 通过url拼接地址
	2. H5本地存储

null和undefined的区别

答:null 表示空值 没有获取到。typeof null 返回"object"
   undefined 表示未定义,声明没有值。typeof undefined 返回"undefined"

Json字符串和json对象怎么相互转换

答: JSON对象转JSON字符串: json.stringify(对象)
    JSON字符串转JSON对象: json.parse(字符串)

怎么理解同步和异步

	1、javascript是单线程。单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。如果前一个任务耗时很长,后一个任务就不得不一直等着。于是就有一个概念——任务队列。
	2、同步任务,顾名思义,就是立即执行的任务,同步任务一般会直接进入到主线程中执行;而异步任务,就是异步执行的任务,比如ajax网络请求,setTimeout 定时函数等都属于异步任务,异步任务会通过任务队列( Event Queue )的机制来进行协调。

37、你对WebSocket了解哪些

答: WebSocket 是HTML5一种新的协议。它实现了浏览器与服务器全双工通信,能更好的节省服务器资源和带宽并达到实时通讯,它建立在TCP之上,同HTTP一样通过TCP来传输数据,但是它和HTTP最大不同是:
	1. WebSocket是一种双向通信协议,在建立连接后,WebSocket服务器和Browser/Client Agent都能主动的向对方发送或接收数据,就像Socket一样;
	2. WebSocket需要类似TCP的客户端和服务器端通过握手连接连接成功后才能相互通信。

38、js的运行机制是什么

答:js是单线程执行的,页面加载时,会自上而下执行主线程上的同步任务,当主线程代码执行完毕时,才开始执行在任务队列中的异步任务。具体如下  
    1.所有同步任务都在主线程上执行,形成一个执行栈。
    2.主线程之外,还存在一个"任务队列(eventloop队列或者消息队列)"。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
    3.一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。哪些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
    4.主线程不断重复上面的第三步。

39、怎么理解面向对象

答:1、面向对象是一种软件开发的思想和面向过程是相对应的,就是把程序看作一个对象,将属性和方法封装其中,以提高代码的灵活性、复用性、可扩展性。
  2、面向对象有三大特性:封装、继承、多态。
       封装:把相关的信息(无论数据或方法)存储在对象中的能力
       继承:由另一个类(或多个类)得来类的属性和方法的能力
       多态:编写能以多种方法运行的函数或方法的能力
   3、js中对象是一个无序的数据集合或者也可以说是属性和方法的集合,可以动态的添加属性可方法。
   4、js是基于对象,但是也使用了嵌入了面向对象的思想,可以实现继承和封装,这样也可以提供代码的灵活性和复用性。

40、如何清除浏览器的缓存

答: 当我们请求的地址相同的时候,浏览器为了提高性能,会把相同地址的数据进行缓存。如果服务端的数据发生改变,客户端也不会更新,那就需要清除缓存
    解决:在url后面加时间戳
    例如:https://www.baidu.com?time=New Date()

列举echarts常用的配置项,说明含义

答:      图表标题 title
		图例  legend
		值域 dataRange
		提示框 tooltip
		区域缩放控制器 dataZoom
		网格 grid
		类目轴 categoryAxis
		值型坐标轴默认参数 valueAxis
		柱形图默认参数 bar
		折线图默认参数 line
		散点图默认参数 scatter
		饼图默认参数 pie
		默认标志图形类型列表 symbolList
		可计算特性配置, 孤岛, 提示颜色 calculable

介绍一下你们公司的开发流程(自己理解,形成自己的东西)

答: (这是最基础的流程,自己理解,形成自己的东西)
    1、项目确定下来后
    2、先分配确定开发人员,然后产品会召集相关开发人员一起开一个项目分析会
    3、接着就项目立项了,项目立项会形成一个prd,确定开发周期
    4、然后就进入开发阶段了,在开发一段时间会进行前后端联调
    5、功能完成后会先进行冒烟测试,检查是否有阻塞缺陷
    6、开发全部结束就进入测试阶段
    7、测试通过就可以上线了,上线之后会有一个回归测试,检查有没有影响以前的功能,保证全流程没有问题

在地址栏输入网址,到数据返回的过程是什么?

:  1. 输入url地址后,首先进行DNS解析,将相应的域名解析为IP地址。
     2. 根据IP地址去寻找相应的服务器。
     3. 与服务器进行TCP的三次握手,建立连接。
     4. 客户端发送请求,找到相应的资源库。
     5. 客户端拿到数据,进行相应的渲染。

原生 ajax 请求的步骤

答:1.创建异步对象 var xhr = new HTMLHttpRequest()
    2.设置请求行  xhr.open()
    3.设置请求头  xhr.setRequestHeader()   get请求没有请求头
    4.设置请求体  xhr.send      get请求没有请求体,参数为null
    5.监视异步对象的状态变化   xhr.onreadystatechange(){}

47、伪数组和真数组的区别

伪数组:
1、拥有length属性
2、不具有数组的方法
3、伪数组是一个Object,真数组是Array
4、伪数组的长度不可变,真数组的长度是可变的

那些情况会得到伪数组

1、参数 arguments,
2DOM 对象列表(比如通过 document.getElementsByTags 得到的列表)、childNodes也是伪数组
3、jQuery 对象(比如 $("div")

伪数组怎么转换为真数组

1let newArr = Array.protype.slice.call(伪数组)
2let newArr = Array.from(伪数组),ES6的新语法
3let newArr = [...伪数组],使用扩展运算符,也是ES6的语法

let、const、var的区别

1var声明变量存在提升(提升当前作用域最顶端),letconst是不存在变量提升的情况
2var没有块级作用,letconst存在块级作用域
3var允许重复声明,letconst在同一作用域不允许重复声明
4varlet声明变量可以修改,const是常量不能改变

异步函数有哪些

JavaScript 中常见的异步函数有:定时器,事件和 ajax 等

什么是promise,特点是什么

	首先,它是一个对象,也就是说与其他JavaScript对象的用法,没有什么两样;它使得异步操作具备同步操作的效果,使得程序具备正常的同步运行的流程,回调函数不必再一层层嵌套。
	简单说,它的思想是,每一个异步任务立刻返回一个Promise对象,由于是立刻返回,所以可以采用同步操作的流程。这个Promises对象有一个then方法,允许指定回调函数,在异步任务完成后调用。
    
 特点:
    1、Promise对象只有三种状态。
        异步操作“未完成”(pending)
        异步操作“已完成”(resolved,又称fulfilled)
        异步操作“失败”(rejected)
        异步操作成功,Promise对象传回一个值,状态变为resolved。
        异步操作失败,Promise对象抛出一个错误,状态变为rejected。
    2、promise的回调是同步的,then是异步的
    3、可以链式调用

promise的方法有哪些,能说明其作用

原型上的方法:
1、Promise.prototype.then()
	1)作用是为 Promise 实例添加状态改变时的回调函数。接受两个回调函数作为参数。第一个回调函数是Promise对象的状态变为resolved时调用,第二个回调函数是Promise对象的状态变为rejected时调用。其中,第二个函数是可选的,不一定要提供。
    2)返回的是另一个Promise对象,后面还可以接着调用then方法。
2、Promise.prototype.catch()
	1)用于指定发生错误时的回调函数。
    2)返回的也是一个 Promise 对象,因此还可以接着调用then方法
3、Promise.prototype.finally()
	1)finally方法用于指定不管 Promise 对象最后状态如何,都会执行的回调函数。
    2)finally方法的回调函数不接受任何参数,这意味着没有办法知道,前面的 Promise 状态到底是fulfilled还是rejected。

自身API:
1、Promise.resolve()
	1)不带参数传递 — 返回一个新的状态为resolve的promise对象
    2)参数是一个 Promise 实例— 返回 当前的promise实例
2、Promise.reject()
	1)返回的是一个值
    2)返回的值会传递到下一个then的resolve方法参数中
3、Promise.all() 
	1)并行执行异步操作的能力
    2)所有异步操作执行完后才执行回调
4、Promise.race()
	1)那个结果返回来的快就是,那个结果,不管结果是成功还是失败

async和await是干什么的

1async 用于申明一个 function 是异步的,而 await 用于等待一个异步方法执行完成。
2await 只能出现在 async 函数中。
3async 函数返回的是一个 Promise 对象,后面可以用then方法。

async和await 原理是什么


怎么理解三次握手

字段	      含义
URG	   紧急指针是否有效。为1,表示某一位需要被优先处理
ACK	   确认号是否有效,一般置为1PSH	   提示接收端应用程序立即从TCP缓冲区把数据读走。
RST	   对方要求重新建立连接,复位。
SYN	   请求建立连接,并在其序列号的字段进行序列号的初始值设定。建立连接,设置为1
FIN    希望断开连接。

1、三次握手
    第一次握手:建立连接时,客户端发送syn包到服务器,等待服务器确认。
    第二次握手:服务器收到syn包,必须确认客户的SYN,同时自己也发送一个SYN包(syn=y)到客户端
    第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK,此包发送完毕,客户端和服务器进入(TCP连接成功)状态,完成三次握手
   (通俗:主机1告诉主机2,我可以向你请求数据吗。主机2告诉主机1,可以请求数据。主机1告诉主机2,那我来请求数据了,请求完成,实现三次握手)

怎么理解四次挥手

1、四次挥手
    第一次分手:主机1(可以使客户端,也可以是服务器端)向主机2发送一个FIN报文段;此时,主机1进入FIN_WAIT_1状态;这表示主机1没有数据要发送给主机2了。
    第二次分手:主机2收到了主机1发送的FIN报文段,向主机1回一个ACK报文段,主机1进入FIN_WAIT_2状态;主机2告诉主机1,我“同意”你的关闭请求。
    第三次分手:主机2向主机1发送FIN报文段,请求关闭连接,同时主机2进入LAST_ACK状态。
    第四次分手:主机1收到主机2发送的FIN报文段,向主机2发送ACK报文段,然后主机1进入TIME_WAIT状态;主机2收到主机1ACK报文段以后,就关闭连接;此时,主机1等待2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,主机1也可以关闭连接了。
    (通俗:主机1告诉主机2,我没有数据要发送了,希望断开连接。主机2接到请求后说,同意断开。主机2告诉主机1可以关闭连接了。主机1接到可以关闭的指令后,关闭连接,四次挥手完成)

数组如何进行降维(扁平化)

1、利用Array.some方法判断数组中是否还存在数组,es6展开运算符连接数组
       let arr = [1,2,[3,4]]
        while (arr.some(item => Array.isArray(item))) {
            arr = [].concat(...arr);
        }
2、使用数组的concat方法
    let arr = [1,2,[3,4]]
     let result = []
     result = Array.prototype.concat.apply([], arr)

3、 使用数组的concat方法和扩展运算符
    var arr = [1,2,[3,4]]
    var result = []
    result = [].concat(...arr)
        
4、es6中的flat函数也可以实现数组的扁平化
    let arr = [1,2,['a','b',['中','文',[1,2,3,[11,21,31]]]],3];
    let result = arr.flat( Infinity )
    注意:flat方法的infinity属性,可以实现多层数组的降维

怎么理解事件循环机制

	1、JavaScript 是一门单线程语言.单线程可能会出现阻塞的情况,所js分了同步任务和异步任务。
    2、同步和异步任务分别进入不同的执行环境,同步的进入主线程,即主执行栈,异步的进入 Event Queue(事件队列) 。主线程内的任务执行完毕为空,会去 Event Queue 读取对应的任务,推入主线程执行。 上述过程的不断重复就是我们说的 Event Loop (事件循环)

什么是作用域链

	1、作用域:分全局作用域和局部作用域
    2、在访问一个变量时,首先在当前作用域中找,如果找不到再到外层作用域中找,这样一层一层的查找,就形成了作用域链。
    3、如果没有找到会返回undefined

for in 和 for of 的区别

1forin是遍历数组、对象的key
2forof是遍历数组的value
例如:
let arr = ["a","b"];
1for (let key in arr) {
console.log(key);  //0 1
}
2for (let value of arr) {
console.log(value);  //a b
}

61、数组去重的方式

1、第一种方式:利用indexof方法
  let arr = [2, 8, 5, 0, 5, 2, 6, 7, 2]
  let newArr = []
  for (let i = 0; i < arr.length; i++) {
     if (newArr.indexOf(arr[i]) === -1) {
       newArr.push(arr[i])
     }
  }

2、第二种方式:sort()方法
   let arr = [2, 8, 5, 0, 5, 2, 6, 7, 2]
   arr.sort()
   let newArr = [arr[0]]
   for (let i = 1; i < arr.length; i++) {
     if (arr[i] !== newArr[newArr.length - 1]) {
       newArr.push(arr[i])
     }
   }
3、第三种方式:两层for循环
    let arr = [2, 8, 5, 0, 5, 2, 6, 7, 2, 8]
    let newArr = []
    for (let i = 0; i < arr.length; i++) {
      for (let j = i + 1; j < arr.length; j++) {
        if (arr[i] === arr[j]) {
          i++
          j = i
        }
      }
     newArr.push(arr[i])
  }
4、第四种方式:利用ES6 Set去重
 let arr = [2, 8, 5, 0, 5, 2, 6, 7, 2, 8]
 let newArr = new Set(arr)

4.webapi/jquery/ajax

AJAX1.项目中后台接口没有写好你怎么做,有几种方式

可以模拟假数据
方式:组件内写死
	  mock.js
      json-serve

5.http/浏览器

!(C:\Users\26798\Desktop\面试题all\微信图片_2021在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
0531143524.jpg)

重排重绘

在这里插入图片描述

在这里插入图片描述

输入url 页面出现前发生什么

在这里插入图片描述

强缓存、协商缓存

在这里插入图片描述

浏览器解析css选择器在这里插入图片描述

6.vue基础知识

vue1.vuex

  1、Vuex 是专为Vue设计的状态管理工具,采用集中式储存管理 Vue 中所有组件的状态。
  2、属性
  (1)state属性:基本数据
  (2)getters属性:从 state 中派生出的数据
  (3)mutation属性:更新 store 中数据的唯一途径,其接收一个以 state 为第一参数的回调函数
  (4)action 属性:提交 mutation 以更改 state,其中可以包含异步操作,数据请求
  (5)module 属性:用于将 store分割成不同的模块,每个模块有自己的state getters mutation action
  namespace:true 命名空间
  
  
  3.使用
  state getters  计算属性  computed
  mutation action  方法里面  methods
  
  页面使用 
    state          this.$store.state.xxx
    mutation      this.$store.commit('方法',参数)
    action         this.$store.dispatch('方法',参数)
    getters         this.$store.getters.xxx 

辅助函数(4个)
import {mapstate} from 'vuex'
...mapState(['num','msg'])   ...mapState('user', ['userInfo'])
...mapMutations(['方法名'])   
...mapActions('user', ['login'])
   

vue2.生命周期

 vue的生命周期:vue实例从创建到销毁的全过程,这个过程可以分为3个阶段   
 第一阶段:初始化阶段   创建vue实例,准备数据,准备模板,渲染视图   
 第二阶段:数据更新阶段 当数据变化时,会进行新旧DOM的对比,对比出差异的部分,进行差异化更新。    
 第三阶段:实例销毁阶段 当vm.$destroy()被调用,vue实例就会被销毁,释放相关资源,此时再更新数据,视图不会再变化。
 

 vue 钩子函数有哪些,有哪些使用的场景
```js
1、各阶段包含钩子: 
beforeCreate  在data数据注入到vm实例之前,此时vm身上没有数据
    created       在data数据注入到vm实例之前,此时vm身上有数据

    beforeMount   生成的结构替换视图之前,此时DOM还没更新
    mounted       生成的结构替换视图之前,此时DOM已经更新完成

    beforeUpdate  数据变化了,dom更新之前
    updated       数据变化了,dom更新之后
    
    activated     被keep-alive缓存的组件激活时调用
    deactivated   被keep-alive缓存的组件停用时调用

    beforeDestroy 实例销毁,是否资源之前
    destroyed     实例销毁,是否资源之后

    这些钩子函数会在vue的生命周期的不同阶段,自动被vue调用

2、常用的钩子函数使用场景:
    beforeCreate  做loading的一些渲染
    created       结束loading, 发送数据的请求,拿数据
    mounted       可以对dom进行操作
    updated       监视数据的更新
    beforeDestroy 销毁非vue资源,防止内存泄漏,例如清除定时器
    activated     当我们运用了组件缓存时,如果想每次切换都发送一次请求的话,需要把请求函数写在activated中,而写在created或mounted中其只会在首次加载该组件的时候起作用。
```

13、Vue 的父组件和子组件生命周期钩子函数执行顺序

1、Vue 的父组件和子组件生命周期钩子函数执行顺序可以归类为以下 4 部分:
  1)加载渲染过程
     父 beforeCreate -> 父 created -> 父 beforeMount -> 子 beforeCreate -> 子 created -> 子 beforeMount -> 子 mounted -> 父 mounted
  2)子组件更新过程
     父 beforeUpdate -> 子 beforeUpdate -> 子 updated -> 父 updated
  3)父组件更新过程
     父 beforeUpdate -> 父 updated
  4)销毁过程
  父 beforeDestroy -> 子 beforeDestroy -> 子 destroyed -> 父 destroyed 

 
 

vue3.自定义指令

// 注册一个全局自定义指令 `v-focus`
Vue.directive('指令名'{钩子函数})
Vue.directive('focus', {
  // 当被绑定的元素插入到 DOM 中时……
  inserted: function (el) {
    // 聚焦元素
    el.focus()
  }
})
钩子函数:
bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
bind.name 指令名
bind.value 指令值
inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
update:所在组件的 VNode 更新时调用

项目里:
// 处理自定义指令模块
// 只封装自定义指令里面核心代码
// 图片加载错误
export const imgerror = {
  inserted(el, binding) {
    el.onerror = function() {
      el.src = binding.value
    }
  }
}
// 处理登录的颜色
export const color = {
  inserted(el) {
    el.style.color = 'red'
  }
}

// 按需导入
// import { color, imgerror } from '@/directives/index'
// Vue.directive('imgerror', imgerror)
// Vue.directive('color', color)

// object.keys()进行指令批量注册
import * as results from '@/directives/index'
// console.log(Object.keys(results))// ["imgerror", "color"]
Object.keys(results).forEach((key, index) => {
  Vue.directive(key, results[key])
})

vue4.过滤器

filter.js
// 处理日期格式
import moment from 'moment'
export function formateDate(value, str = 'YYYY年MM月DD日') {
  return moment(value).format(str)
}

main.js
// 注册全局过滤器
import * as filters from '@/filters/index'
Object.keys(filters).forEach(key => {
  Vue.filter(key, filters[key])
})

页面中使用用管道符|  {{}}

vue5.vue-router 、路由模式、导航守卫

1。
vue-router是Vue.js官方路由的实例,vue深度集成了
原理:路径切换 url 与页面的映射关系
哈希  history 实现方式


2.一般有两种模式:
        1、hash 模式:后面的 hash 值的变化,浏览器既不会向服务器发出请求,浏览器也不会刷新,每次 hash 值的变化会触发 hashchange 事件。
        2、history 模式:利用了 HTML5 中新增的 pushState()replaceState() 方法。这两个方法应用于浏览器的历史记录栈,在当前已有的 back、forward、go 的基础之上,它们提供了对历史记录进行修改的功能。只是当它们执行修改时,虽然改变了当前的 URL,但浏览器不会立即向后端发送请求。
        
3.导航守卫

在这里插入图片描述



// 后台系统pc端如果一个用户没有登录过的,不可以访问首页
// 全局前置守卫拦截,放行之后才会真正进入页面 导入router即可
import router from '@/router'
import store from '@/store'
// import { asyncRoutes } from '@/router/index'
// 处理进度条
import NProgress from 'nprogress' // 引入一份进度条插件
import 'nprogress/nprogress.css' // 引入进度条样式
const whiteList = ['/login', '/404']
// 全局导航前置守卫
router.beforeEach(async(to, from, next) => {
  // 获取个人信息调用
  NProgress.start()
  const token = store.getters.token
  // 如果有token
  if (token) {
    // 是否是登录页,跳到主页
    if (to.path === '/login') {
      next('/')
    } else {
      // console.log(res)
      // setTimeout(() => {
      //   console.log(1)
      // }, 2000)

      // alert('我先打印')
      // next()
      // 判断是否拿到用户身份角色,判断userInfo对象中的一个属性是否有值
      if (!store.state.user.userInfo.userId) {
        // 获取个人信息,拿到用户身份角色后,才放行
        const { roles } = await store.dispatch('user/getUserInfo')
        // 提交actions
        const otherRoutes = await store.dispatch('permission/filterRoutes', roles.menus)
        //   router.addRoutes 添加路由往路由配置规则数组里面的最后面追加
        router.addRoutes([
          ...otherRoutes,
          { path: '*', redirect: '/404', hidden: true }
        ]
        )
        // next()
        next({
          ...to, // 重进一次
          replace: true// 不保留重复的路由,重进一次
        })
        return
      }
      next()
    }
  } else {
    // 没有token,是否在白名单
    if (whiteList.includes(to.path)) {
      next()
    } else {
      next('/login')
    }
  }
})

//  全局导航后置守卫
router.afterEach((to, from) => {
  NProgress.done()
})

vue6. route router

1、$router对象
    1)$router对象是全局路由的实例,是router构造方法的实例
    2)$router对象上的方法有:push()、go()、replace()
2、$route对象
    1)$route对象表示当前的路由信息,包含了当前 URL 解析得到的信息。包含当前的路径,参数,query对象等
    2)$route对象上的属性有:path、params、query、hash等等
   

vue7.nextTick()原理

背景:
	1、简单来说,Vue 在修改数据后,视图不会立刻更新,而是等同一事件循环中的所有数据变化完成之后,再统一进行视图更新。
    
定义:
	2、在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。nextTick(),是将回调函数延迟在下一次dom更新数据后调用,简单的理解是:当数据更新了,在dom中渲染后,自动执行该函数。
    
原理
	3、vue用异步队列的方式来控制DOM更新和nextTick回调先后执行。
	简单来说,nextTick是做了promise加上setTimeout的封装,利用事件换行机制,来确保当nextTick出现时,都是在我们所有操作DOM更新之后的。

场景:
	4.1 点击获取元素宽度
    4.2 使用swiper插件通过 ajax 请求图片后的滑动问题
    4.3 点击按钮显示原本以 v-show = false 隐藏起来的输入框,并获取焦点

vue8.key作用

作用:      1.key的作用主要是为了高效的更新虚拟DOM,提高渲染性能。      
            2.key属性可以避免数据混乱的情况出现。
 原理:   1.vue实现了一套虚拟DOM,使我们可以不直接操作DOM元素只操作数据,就可以重新渲染页面,而隐藏在背后的原理是高效的Diff算法
      2.当页面数据发生变化时,Diff算法只会比较同一层级的节点;
      3.如果节点类型不同,直接干掉前面的节点,再创建并插入新的节点,不会再比较这个节点后面的子节点;
        如果节点类型相同,则会重新设置该节点属性,从而实现节点更新
      4.使用key给每个节点做一个唯一标识,Diff算法就可以正确失败此节点,"就地更新"找到正确的位置插入新的节点。            

vue9.虚拟DOM

vue10.diff算法

在这里插入图片描述

vue11.组件传值

在这里插入图片描述

5.vuex  多组件共享数据
数据是响应式的

vue12.组件子父拿方法属性

父组件怎么用子组件的方法 ref this.$refs.xxx()
子组件怎么用父组件的方法 this.$parent

vue13.style样式scoped

用途:防止全局同名CSS污染
原理:在标签加上v-data-something属性,再在选择器时加上对应[v-data-something],即CSS带属性选择器,以此完成类似作用域的选择方式.   
scoped会在元素上添加唯一的属性(data-v-x形式),css编译后也会加上属性选择器,从而达到限制作用域的目的。

vue14.路由传参、组件中监听路由参数变化

只能用在包含<router-view /> 的组件内
1.watch:{                              2.beforeRouteUpdate(to,from,next){
    '$route'(to,from){                   此处监听
    此处监听                                }
    }
}                  

::v-deep 深度选择器 scss             css >>>    less  /deep/
!important

在这里插入图片描述

vue15.路由配置项


vue16.vue首屏加载优化

v-if 和 v-show 区分使用场景
computed 和 watch  区分使用场景
v-for 遍历必须为 item 添加 key,且避免同时使用 v-if
长列表性能优化
事件的销毁 addEventlisenter 事件监听
图片资源懒加载
精灵图
路由懒加载
第三方插件的按需引入
优化无限列表性能
服务端渲染 SSR 
代码压缩

vue17.单向数据流

数据从父级组件传递给子组件,只能单向绑定
子组件内部不能直接修改从父级传递过来的数据
子组件想修改时,this.$emit()
.sync修饰符

vue18.v-if v-show

v-if和v-show的区别,使用场景区别
v-if和v-show看起来似乎差不多,当条件不成立时,其所对应的标签元素都不可见,但是这两个选项是有区别的:
1、v-if在条件切换时,会对标签进行适当的创建和销毁,而v-show则仅在初始化时加载一次,因此v-if的开销相对来说会比v-show大。
2、v-if是惰性的,只有当条件为真时才会真正渲染标签;如果初始条件不为真,则v-if不会去渲染标签。v-show则无论初始条件是否成立,都会渲染标签,它仅仅做的只是简单的CSS(display)切换。

3、 v-if适用于不需要频繁切换元素显示和隐藏的情况
    v-show适用于需要频繁切换元素的显示和隐藏的场景。

vue19.事件修饰符和按键修饰符有哪些

事件修饰符:
	.prevent  阻止事件默认行为
    .stop     阻止事件冒泡
    .capture  设置事件捕获机制
    .self     只有点击元素自身才能触发事件
    .once     事件只触发一次
 按键修饰符:
    .tab
    .enter
    .esc
    .space
    .delete(捕获"删除""空格")
    .up
    .down
    .left
    .right

vue20.怎么理解mvvm这种设计模式

 Model–View–ViewModel (MVVM) 是一个软件架构设计模式,是一种简化用户界面的事件驱动编程方式。
MVVM
    M Model 模型 指的是数据层
    V View  视图 指的是用户页面
    VM ViewModel 视图模型
    视图模型是MVVM模式的核心,它是连接view和model的桥梁,MVVM实现了view和model的自动同步,当model的属性改变时,我们不用自己手动操作DOM元素,来改变view的显示,反之亦然,我们称之为数据的双向绑定。

vue21.组件中的data为什么是函数,new Vue 实例里,data 可以直接是一个对象

1、组件是用来复用的,组件中的data写成一个函数,数据以函数返回值形式定义,函数有独立的作用域,这样每复用一次组件,就会返回一份新的data,类似于给每个组件实例创建一个私有的数据空间,让各个组件实例维护各自的数据。
2、而单纯的写成对象形式,由于对象是引用类型,就使得所有组件实例共用了一份data,就会造成一个变了全都会变的结果。
3、因为new vue里面的代码是不存在复用的情况,所以可以写成对象形式

data重置 Object.assgin(目标对象,...源对象)
this.$options.data(this) 初始化状态下的data

vue22.computed和watch的区别是什么

计算属性computed:

1、支持缓存,只有依赖数据发生改变,才会重新进行计算
2、不支持异步,当computed内有异步操作时无效,无法监听数据的变化
3、如果computed需要对数据修改,需要写getset两个方法,当数据变化时,调用set方法。
4、computed擅长处理的场景:一个数据受多个数据影响,例如购物车计算总价

侦听属性watch:

1、不支持缓存,数据变,直接会触发相应的操作;
2、watch支持异步;监听的函数接收两个参数,第一个参数是最新的值;第二个参数是输入之前的值;
3、immediate:组件加载立即触发回调函数执行
4、deep:true的意思就是深入监听,任何修改obj里面任何一个属性都会触发这个监听器里的 handler方法来处理逻辑
5、watch擅长处理的场景:一个数据影响多个数据,例如搜索框


不应该使用箭头函数来定义 watch :例如:    watch: {   
    a: () => {  //  这里不应该用箭头函数      
        console.log(this);        
        this.sum = this.a + this.b;      
    } 
     })   
    理由是箭头函数绑定了父级作用域的上下文,所以 this 将不会按照期望指向 Vue 实例,this.a 将是 undefined。
    注意:methods里面定义的方法也不要用箭头函数

vue23.组件化和模块化的区别

1、组件相当于库,把一些能在项目里或者不同类型项目中可复用的代码进行工具性的封装。
2、模块相应于业务逻辑模块,把同一类型项目里的功能逻辑进行进行需求性的封装。

vue24.vue是如何获取DOM

1、先给标签设置一个ref值,再通过this.$refs.domName获取,这个操作要在mounted阶段进行。
2、例如:
<template>
	<div ref="test"></div>
</template>
mounted(){
   const dom = this.$refs.test 
}

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

可以
例如:
<input type="text" v-on="{ input:onInput,focus:onFocus }">

vue26.谈谈你对slot的了解

1、什么是插槽
	1.1 插槽(Slot)是Vue提出来的一个概念,正如名字一样,插槽用于决定将所携带的内容,插入到指定的某个位置,从而使模板分块,具有模块化的特质和更大的重用性。
	1.2 插槽显不显示、怎样显示是由父组件来控制的,而插槽在哪里显示就由子组件来进行控制
    
2、插槽使用
	2.1 默认插槽  在子组件中写入slot,slot所在的位置就是父组件要显示的内容
    2.2 具名插槽  在子组件中定义了三个slot标签,其中有两个分别添加了name属性header和footer
    			 在父组件中使用template并写入对应的slot名字来指定该内容在子组件中现实的位置
    2.3 作用域插槽  在子组件的slot标签上绑定需要的值<slot :data="user"></slot>
    	          在父组件上使用slot-scope=“user”来接收子组件传过来的值 

vue27.vue中动态组件如何使用

1、在某个中使用 is 特性来切换不同的组件:
	<component :is="TabComponent"></component>   TabComponent:已注册组件的名字

vue28.v-model的原理是什么

1、v-model主要提供了两个功能,view层输入值影响data的属性值,属性值发生改变会更新层的数值变化.
2、v-model指令的实现:
	3.1 v-bind:绑定响应式数据
	3.2 触发input事件并传递数据 (核心和重点)
3、其底层原理就是(双向数据绑定原理)3.1 一方面modal层通过defineProperty来劫持每个属性,一旦监听到变化通过相关的页面元素更新。
    3.2 另一方面通过编译模板文件,为控件的v-model绑定input事件,从而页面输入能实时更新相关data属性值。

vue29.vue响应式vue的原理

1、原理:
	Vue 的响应式原理是核心是通过 ES5 的 Object.defindeProperty 进行数据劫持,然后利用 getset 方法进行获取和设置,data 中声明的属性都被添加到了getset中,当读取 data 中的数据时自动调用 get 方法,当修改 data 中的数据时,自动调用 set 方法,检测到数据的变化,会通知观察者 Wacher,观察者 Wacher自动触发重新render 当前组件(子组件不会重新渲染),生成新的虚拟 DOM 树,Vue 框架会遍历并对比新虚拟 DOM 树和旧虚拟 DOM 树中每个节点的差别,并记录下来,最后,加载操作,将所有记录的不同点,局部修改到真实 DOM 树上。

2、底层代码实现:
	   let data = {
        name: "lis",
        age: 20,
        sex: "男"
    }
//  vue2.0实现  使用Object.defineProperty进行数据劫持
    for(let key in data){
        let temp = data[key]
        Object.defineProperty(data, data[key], {
            get(){
                return temp
            },
            set(value){
                temp = value
            }
        })
    }
// vue3.0实现 使用Proxy 进行数据的代理
    let newData = new Proxy(data, {
        get(target, key){
            return target[key]
        },
        set(target, key, value){
            target[key] = value
        }
    })

vue30.vue2.0和vue3.0响应式的区别

1、Object.defineProperty 
  1) 用于监听对象的数据变化
  2) 无法监听数组变化(下标,长度)
  3) 只能劫持对象的自身属性,动态添加的劫持不到
2、Proxy
  1) proxy返回的是一个新对象, 可以通过操作返回的新的对象达到目的
  2)可以监听到数组变化,也可以监听到动态添加的数据

vue31.Vue模版编译原理知道吗,能简单说一下吗

1、简单说,Vue的编译过程就是将template转化为render函数的过程。
2、首先解析模版,生成AST语法树(一种用JavaScript对象的形式来描述整个模板)。 使用大量的正则表达式对模板进行解析,遇到标签、文本的时候都会执行对应的钩子进行相关处理。
3、Vue的数据是响应式的,但其实模板中并不是所有的数据都是响应式的。有一些数据首次渲染后就不会再变化,对应的DOM也不会变化。那么优化过程就是深度遍历AST树,按照相关条件对树节点进行标记。这些被标记的节点(静态节点)我们就可以跳过对它们的比对,对运行时的模板起到很大的优化作用。
4、编译的最后一步是将优化后的AST树转换为可执行的代码。

vue32.SSR了解吗

1SSR也就是服务端渲染,也就是将Vue在客户端把标签渲染成HTML的工作放在服务端完成,然后再把html直接返回给客户端。
2SSR有着更好的SEO、并且首屏加载速度更快等优点。不过它也有一些缺点,比如我们的开发条件会受到限制,服务器端渲染只支持beforeCreate和created两个钩子,当我们需要一些外部扩展库时需要特殊处理,服务端渲染应用程序也需要处于Node.js的运行环境。还有就是服务器的压力比较大。

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

1、v-if和v-for不能连用
2、页面采用keep-alive缓存组件
3、合理使用v-if和v-show
4、key保证唯一
5、使用路由懒加载、异步组件、组件封装
6、防抖、节流
7、第三方模块按需导入
8、图片懒加载
9、精灵图的使用
10、代码压缩

vue34.怎么解决vue打包后静态资源图片失效的问题

在vue-cli 需要在根目录下建一个vue.config.js 在里面配置publicPath即可
默认值为/,更改为./就好了

vue35.怎么解决vue动态设置img的src不生效的问题

因为动态添加src被当做静态资源处理了,没有进行编译,所以要加上require。
<img :src="require('@/assets/images/xxx.png')" />

vue36.EventBus注册在全局上时,路由切换时会重复触发事件,如何解决呢

原因:因为我们的事件是全局的,它并不会随着组件的销毁而自动注销,需要我们手动调用注销方法来注销。
解决:我们可以在组件的 beforeDestroy ,或 destroy 生命周期中执行注销方法,手动注销事件

vue36.你认为vue的核心是什么

组件化
双向数据绑定

vue37.在.vue文件中style是必须的吗?那script是必须的吗

.vue 文件中,template是必须的,而script与style都不是必须的。都没有的话那就是一个静态网页

vue38.说说vue的优缺点

优点:
    1.数据驱动
    2.组件化
    3.轻量级
    4.SPA(单页面)
    5.版本3.0的界面化管理工具比较好使
    6.vue易入门
    7.中文社区强大,入门简单,提升也有很多的参考资料。
缺点:
    1.不支持IE8及以下浏览器
    2.吃内存(每个组件都会实例化一个Vue实例,实例的属性和方法很多)
    3.定义在data里面的对象,实例化时,都会递归的遍历转成响应式数据,然而有的响应式数据我们并不会用到,造成性能上的浪费

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

 v-for优先级高于v-if
    如果同时出现v-for和v-if,无论判断条件是否成立,都会执行一遍v-for循环,这样浪费性能,所以要尽可能的避免两者一起使用。

vue40.插槽

在这里插入图片描述

vue41.组件中的name选项作用

在这里插入图片描述

vue42.组件的命名规范在这里插入图片描述

vue7.项目技术点

Project0.项目介绍

在这里插入图片描述

interceptors:【ɪntərˈsɛptərz】
1、项目中会在utils文件中,封装一个request.js文件
2、通过axios.create()配置baseURL,并得到一个request实例
3、通过request.interceptors.request.use来配置请求拦截
4、通过request.interceptors.response.use来配置响应拦截

Project1.权限控制

前端这边:
1.页面访问权(菜单显示)
vue-router+vuex路由权限控制
登录时通过路由前置守卫发送请求获取权限信息
在vuexstate中定义route用于存储路由信息,默认为静态路由
在action中定义一个fiterRoute方法用于过滤动态路由对象,具体实现:
在vuex中引入所有动态路由对象,fiterRoute中接收一个参数(后台获取到的动态路由信息),接着将动态路由对象与动态路由信息利用filter进行过滤,返回过滤出来的对象
在前置守卫中调用这个filterRoute把后台请求到的路由信息传过去,就可以接收到过滤完之后的动态路由对象
最后利用addRoutes添加到路由规则里

2.按钮操作权 
后台返回数据里面可以拿到按钮操作权的字段信息, v-if 按钮的禁用启用(disabled)

Project2.token存储

token存储 (封装本地存储、将token存储到请求拦截器中)
token理解: token就是后台(服务器)根据用户信息通过一套算法加密处理过的字符串返回给客户端,是用户身份的唯一标识
前台没有能力生成token,我们写的是假字符串
一般用户登录后(第一次请求的数据),本地就会有存储
token的存储:本地存储和vuex都存储一份
本地存储一份  localstorage cookie 数据持久化 要自己手动获取  
vuex中存储一份  响应式数据  方便获取   
注意:本地存储的是字符串格式
    vuex默认刷新的时候会出现丢失状态的问题,所以需要配合本地存储去用
1.utils工具文件夹中建一个js模块 
存在localstorage    storage.js
封装一个关于本地存储的方法
设置一个token名字
const Token-key='xxx'
封装三个函数分别用来setToken getToken removeToken 并导出
里面用到 localStorage.setItem
                     .getItem
                     removeItem 
存在cookie其实也一样  auth.js(认证)
原生的cookie很麻烦,需要操作字符串,键值对的形式,一拿拿到所有的cookie信息 
所以我们子昂木中用的是插件 js-cookie 
安装插件导入 import Cookies from 'js-cookie'
cookies.get
cookies.set
cookies.remove
使用就跟localStorage差不多了

在vuex中的用户模块
state中存储token
去本地里面localStorage/cookie里面拿
token:getToken()
action发请求,登录后提交一个mutation setToken,将state里面的token进行更新,并且将这个token存储到本地
退出登录,提交removeToken的mutation 删除本地token 将state里面的token设置为null

                     

Project3.token过期处理

经验四:
token过期理解:
1.token需要过期时间的,比如支付宝/微信的付款码,过期时间取决于后台设置,一旦过期,一定要处理,否则用户就不能操作有权限的页面了
2.token过期怎么处理
(1)一是重复第一次获取token的过程(比如登录,扫描授权等),这样做的缺点是用户体验不好
(2).采用双token,让refresh token 主动刷新token也是加密字符串,并且和token是相关联的。相比可以获取各种资源的token,refresh token的作用仅仅是获取新的token,因此其作用和安全性要求都大为降低,所以其过期时间也可以设置得长一些。 
理解:过期后,需要权限的接口需要携带token获取数据,因为token过期,在我们项目中就会返回一个401的错误,有的公司token过期会直接拦截到登录页面重新登录,refresh_token刷新token ,也是一个字符串,也会过期,过期时间一般15天左右,如果refresh_token也过期了,就只能回到登录页面重新登录​

3.处理token:
(1)单token
(2)双token(后台设计的)token 发请求需携带refresh_token刷新tokentoken+refresh_token好处:即使token过期了,让用户无感知的操作页面
//处理过期思路:1.响应拦截器中 响应失败的函数,在这个函数中刷新token判断状态码 401刷新token token刷新依赖refresh_token 先判断有没有refresh_token 没有就直接去登录
2.有refresh_token 刷新token 封装接口 获取新token为了代码的健壮性,要清除本地和vuex中失效的信息
3.新token存储在vuex和本地存储
4.重新发送上一次失败的请求(修改上一次失败请求过期的token)5.refresh_token过期的处理,直接去登录

Project4.组件缓存在这里插入图片描述

Project5.列表数据转换树形数据(递归)

在这里插入图片描述

Project6.组件封装

1.创建一个组件(使用Vue.extend()2.使用Vue.component()方法注册组件
3.如果子组件需要数据,可以在props中接受定义
4.子组件修改好数据之后,想把数据传递给父组件,可以使用emit()方法

封装公共的头部组件
  头部组件抽离
      	1)抽离一个headerTop
        2) 组件内容接受标题或标签
        	<template>
          		<slot name="left"></slot>
                <div>{{title}}</div>
                <slot name="right"></slot>
            </template>
                props:['title']
         3) 其他组件引入
         	 components:{HeaderTop}
		 4) 组件内使用
         	 <HeaderTop title="标题">
               	<div slot='left'>左边内容</div>
                <div slot='right'>右边内容</div>
             </HeaderTop>

Project7.vue踩的坑

1.给对象添加属性的时候 ,直接通过data里面的对象添加属性然后赋值,新添加的属性不是响应式的
解决办法:this.$set(对象,属性,值)
数组长度,新增数组项  this.array.splice(newLENGTH)
2.在created操作dom,Dom还没有渲染出来,报错,获取不到的
this.$nextTick(回调函数进行获取)

MobieProject8.处理相对时间

相对时间处理  几天前
// 处理时间格式的js模块
import dayjs from 'dayjs'
// dayjs 安装之后只有一个方法, 用别的方法需要导入并添加扩展
// 1.导入相对时间的扩展包
import relativeTime from 'dayjs/plugin/relativeTime'
// 导入中文语言包后去注册中文语言
import 'dayjs/locale/zh-cn'
dayjs.locale('zh-cn')
// 2. 扩展给dayjs
dayjs.extend(relativeTime)
// 封装一个处理时间格式的方法
export const formatTime = (val) => {
  return dayjs(val).format('YYYY-MM-DD')
}
// 封装一个处理相对时间格式的方法
// .from .to .fromNow .toNow 没有什么大的差别 显示格式上 xxx前  xx内
export const getRelativeTime = (val) => {
  return dayjs(val).from()
}

MobieProject9.大数据处理

大数字处理
 import http from '@/utils/request'
 导入处理大数字的包 JSONbig这个包也有两个方法
 JSONbig.stringify() JSONbig.parse()
 手动处理响应的数据,在封装axios实例里面
  transformResponse: [function (data) {
    // data就是响应的数据 只不过是字符串格式的
    // json-bigint 这个包是专门处理大数字的包
    // 后台有可能响应的数据不是json格式的字符串, 转换就会报错, 当前项目中没有这个问题
    try {
      return JSONbig.parse(data)
    } catch (error) {
      return data
    }
  }]

MobieProject10.移动端机器人对话

 对话时, 内容区域不会自己滚动到底部
解决:可以给scrollTop设置scrollHeight的值
通过ref获取dom元素 $nextTick()处理 
this.$refs.refList.scrollTop = this.$refs.refList.scrollHeight


        
 在浏览商品时,点击商品详情,然后返回,要求进度条还在之前的位置,怎么做

1、App.vue页面中使用keep-alive缓存组件
2、在离开商品详情页记录进度条的高度,返回商品详情的重新给进度条进行赋值

MobieProject11.处理搜索关键字高亮,不能全部替换,以及大小写

处理搜索关键字高亮,不能全部替换,以及大小写
	// 1. 正则表达式的创建方式    new RegExp(匹配的字符, 匹配规则)
	 可以解析变量k  正则的结果是 
     let reg = new RegExp(k, 'gi') 
		// replace方法第一个参数是匹配的字符(可以传递正则表达式) 
		// 参数2 可以是一个字符串还可以是一个函数函数中的参数就是匹配到的字符 而且函数必须有返回值
		let res = str.replace(reg, (str)=>{
			return `<span style="color: red">${str}</span>`
		})
        


Project13.跨域问题

在这里插入图片描述

Project14.webpack在项目中配置



1、 配置兼容编译ES6转成ES5
	用babel来编译,npm i babel-core babel-loader babel-preset-env babel-polyfill babel-plugin-transform-runtime --save-dev
2、配置跨域代理服务
	用proxy进行代理,在devServer里面配置,proxy:{'/api':{target:代理的地址}}
3、配置打包路径
	publicPath:'/'
4、配置打包出去文件
	outputDir: 'dist'
5、配置执行环境变量
	启动的端口  const port = process.env.port || process.env.npm_config_port || 9528
	

Project15.axios封装

1.在Utils中的request.js里面,引入axios,配置基础路径、请求拦截器和响应拦截器,并返回axios
2、在api文件里面,引入request.js,根据各组件需要,配置各个组件的接口请求文件

vue项目里用axios发请求:
axios有请求响应拦截器
axios支持promise对象
用ajax,可能要倒下jquery库

8.人事问题/面试最后提问

9.git

git1.怎么处理冲突


如何处理git的冲突:就是百度

1、为什么产生冲突?
当两个人同时改了同一处代码会产生冲突
2、什么时候会产生冲突?
当你要push代码的时候,我们一般先要pull一下,也就是拉取远程代码,
当你pull的时候如果远程有人改了你写的代码就会冲突,
冲突了你要看是哪里冲突,是谁修改了你的代码,然后找修改你代码的人去商量,到底谁是正确的,有了商量的结果后,用正确的代码覆盖错误代码就行

git2.常用命令


//1.创建远程仓库,写名就可以,直接创建
//2.本地已有仓库的管理git remote add origin  自己的仓库地址(ssh)
                   git push -u origin master
//3.运行相关命令
git init  初始化仓库
git clone 克隆代码到本地
git status 查看状态
git add . 添加
git commit -m 'init project' 提交
git push 推送到远程仓库
git pull 拉取代码到本地
git branch dev 创建分支
git branch -d 分支名称  删除分支
git checkout login 切换分支
git merge master 合并分支
git log 查看提交日志
git reset 版本号   版本回退 

git merge  /rebase 有什么区别
会自动产生 merge commit   详细合并信息
不会自动产生 merge commit  简洁,无提交历史

在仓库的根目录创建一个`.gitignore`的文件,文件名是固定的。
将不需要被git管理的文件路径添加到`.gitignore`

git3.git工作流

master 主分支(稳定代码)
develop 主开发分支
    feature 新功能分支
    release 发布分支(测试)
    hotfix 热补丁分支

 有一个master分支
1.有一个dev分支,写新功能,在dev分支上新开分支,写功能
2.如果功能写完了,合并到dev分支
3.将dev分支新增功能,合并release分支,进行测试,bug修复
4.将修复好的release 分支代码合并到master和dev上
5.将master的代码,用于真实上线
6.如果上线代码遇到错误,开一个hotfix的分支调试 

10.补充兼容:

PC端的兼容问题你遇到那些

1、img下的留白
	解决方案:给img设定display:block。

2、如果图片加a标签在IE9-中会有边框
	解决方案:给img设定border:none。

3、rgba不支持IE8
	解决方案:可以用 opacity

4、标签最低高度设置min-height不兼容ie6/7
	解决方案:如果我们要设置一个标签的最小高度200px,需要进行的设置为:{min-height:200px; height:auto !important; height:200px; overflow:visible;}

5、图片加a标签在IE9中出现边框
	解决方案: img{border: none;}

移动端的兼容问题你遇到那些

1、在ios和andriod中,audio元素和video元素在无法自动播放
    应对方案:触屏即播
    $('html').one('touchstart',function(){
        audio.play()
    })
2、iOS 系统中文输入法输入英文时,字母之间可能会出现一个六分之一空格
	可以通过正则去掉: this.value = this.value.replace(/\u2006/g, '');

3IOS移动端click事件300ms的延迟响应
	引入第三方插件fastclick可以解决在手机上点击事件的300ms延迟
 
4、 h5底部输入框被键盘遮挡问题
    h5页面有个很蛋疼的问题就是,当输入框在最底部,点击软键盘后输入框会被遮挡。可采用如下方式解决
    1)定义一个class:
		.focusState {position: absolute;}
	2)利用监听键盘的收起展开事件来添加移除定义的focusState 样式
    	 created(){
    		var clientHeight = document.documentElement.clientHeight || document.body.clientHeight;
    		window.onresize = function() {
              // onresize 事件会在窗口或框架被调整大小时发生
        	var nowClientHeight = document.documentElement.clientHeight || document.body.clientHeight;
        	if (clientHeight - nowClientHeight > 60 ) {//因为ios有自带的底部高度
            	//键盘弹出的事件处理
            	document.getElementById("apply").classList.add("focusState");
                // classList 该属性用于在元素中添加, 移除及切换 CSS 类
        	}
       		else {
            	//键盘收起的事件处理
        		document.getElementById("apply").classList.remove("focusState");
        	} 
    	};
	},

移动端如何做真机测试

方式1、公司有测试服务器,代码放到测试服务器上,进行手机访问测试
方式2、自己电脑上搭服务器,保证自己手机和电脑处于同一个局域网,然后用手机进行访问测试

H5和app的区别

1H5是通过链接进行访问,而APP是通过应用程序进行访问
2H5在应用商店里面没有,而APP是有的
3H5不需要审核就可以上线,而APP是需要审核的
4H5的响应速度没有APP5H5的开发成本比APP

怎么知道自己项目所处的环境是什么

1、看ip和端口地址
2、启动项目方式

cli用的是那个版本和src里面都有哪些文件

版本:
    Vue      2.6.10 版本
    vuex     3.1.0  版本
    Vue-cli  4.4.4  版本
    webpack  4.4.0  版本
    
 src:
	api         接口请求
    assets      静态图片
    components  公共组件
    icons		字体图标
    router		路由配置
    store		vuex
    utils		axios封装
    views		页面级路由 

### git3.git工作流

```js
master 主分支(稳定代码)
develop 主开发分支
    feature 新功能分支
    release 发布分支(测试)
    hotfix 热补丁分支

 有一个master分支
1.有一个dev分支,写新功能,在dev分支上新开分支,写功能
2.如果功能写完了,合并到dev分支
3.将dev分支新增功能,合并release分支,进行测试,bug修复
4.将修复好的release 分支代码合并到master和dev上
5.将master的代码,用于真实上线
6.如果上线代码遇到错误,开一个hotfix的分支调试 

10.补充兼容:

PC端的兼容问题你遇到那些

1、img下的留白
	解决方案:给img设定display:block。

2、如果图片加a标签在IE9-中会有边框
	解决方案:给img设定border:none。

3、rgba不支持IE8
	解决方案:可以用 opacity

4、标签最低高度设置min-height不兼容ie6/7
	解决方案:如果我们要设置一个标签的最小高度200px,需要进行的设置为:{min-height:200px; height:auto !important; height:200px; overflow:visible;}

5、图片加a标签在IE9中出现边框
	解决方案: img{border: none;}

移动端的兼容问题你遇到那些

1、在ios和andriod中,audio元素和video元素在无法自动播放
    应对方案:触屏即播
    $('html').one('touchstart',function(){
        audio.play()
    })
2、iOS 系统中文输入法输入英文时,字母之间可能会出现一个六分之一空格
	可以通过正则去掉: this.value = this.value.replace(/\u2006/g, '');

3IOS移动端click事件300ms的延迟响应
	引入第三方插件fastclick可以解决在手机上点击事件的300ms延迟
 
4、 h5底部输入框被键盘遮挡问题
    h5页面有个很蛋疼的问题就是,当输入框在最底部,点击软键盘后输入框会被遮挡。可采用如下方式解决
    1)定义一个class:
		.focusState {position: absolute;}
	2)利用监听键盘的收起展开事件来添加移除定义的focusState 样式
    	 created(){
    		var clientHeight = document.documentElement.clientHeight || document.body.clientHeight;
    		window.onresize = function() {
              // onresize 事件会在窗口或框架被调整大小时发生
        	var nowClientHeight = document.documentElement.clientHeight || document.body.clientHeight;
        	if (clientHeight - nowClientHeight > 60 ) {//因为ios有自带的底部高度
            	//键盘弹出的事件处理
            	document.getElementById("apply").classList.add("focusState");
                // classList 该属性用于在元素中添加, 移除及切换 CSS 类
        	}
       		else {
            	//键盘收起的事件处理
        		document.getElementById("apply").classList.remove("focusState");
        	} 
    	};
	},

移动端如何做真机测试

方式1、公司有测试服务器,代码放到测试服务器上,进行手机访问测试
方式2、自己电脑上搭服务器,保证自己手机和电脑处于同一个局域网,然后用手机进行访问测试

H5和app的区别

1H5是通过链接进行访问,而APP是通过应用程序进行访问
2H5在应用商店里面没有,而APP是有的
3H5不需要审核就可以上线,而APP是需要审核的
4H5的响应速度没有APP5H5的开发成本比APP

怎么知道自己项目所处的环境是什么

1、看ip和端口地址
2、启动项目方式

cli用的是那个版本和src里面都有哪些文件

版本:
    Vue      2.6.10 版本
    vuex     3.1.0  版本
    Vue-cli  4.4.4  版本
    webpack  4.4.0  版本
    
 src:
	api         接口请求
    assets      静态图片
    components  公共组件
    icons		字体图标
    router		路由配置
    store		vuex
    utils		axios封装
    views		页面级路由 

AMD CMD common.js es6模块化

[外链图片转存中…(img-17在这里插入图片描述
在这里插入图片描述
在这里插入图片描述