面试校招基础

# 介绍

自己介绍

面试人介绍

面试结束后,提问给自己

# 项目

# 基础

# HTML基础

# 浏览器解析渲染页面

浏览器拿到响应文本 HTML 后,接下来介绍下浏览器渲染机制

Webkit main flow

浏览器解析渲染页面分为一下五个步骤:【DCJ渲布绘】

  • 根据 HTML 解析出 DOM 树
  • 根据 CSS 解析生成 CSS 规则树
  • 结合 DOM 树和 CSS 规则树,生成渲染树
  • 根据渲染树计算每一个节点的信息
  • 根据计算好的信息绘制页面

# cookies,sessionStorage和localStorage区别

名称 生命期 大小限制 与服务器通信
cookie 一般由服务器生成,可设置失效时间。如果在浏览器端生成Cookie,默认是关闭浏览器后失效 4KB 每次都会携带在HTTP头中,如果使用cookie保存过多数据会带来性能问题
sessionStorage 仅在当前会话下有效,关闭页面或浏览器后被清除 5MB 仅在浏览器中保存,不与服务器通信
localStorage 除非被清除,否则永久保存 5MB 仅在浏览器中保存,不与服务器通信

# HTTP

# http版本的比较

版本 内容
http0.9 只允许客户端发送 GET 这一种请求;且不支持请求头,协议只支持纯文本;无状态性,每个访问独立处理,完成断开;无状态码
http1.0 解决 0.9 的缺点,增加 If-modify-since(last-modify)和 expires 缓存属性
http1.x 增加 cache-control 和 If-none-match(etag)缓存属性
http2.0 采用二进制格式传输;多路复用;报头压缩;服务器推送
http3.0 采用 QUIC 协议,自定义连接机制;自定义重传机制;无阻塞的多路复用

# HTTP状态码

# 比较分类

序列 详情
1XX(通知) 代表请求已被接受,需要继续处理。这类响应是临时响应,只包含状态行和某些可选的响应头信息,并以空行结束。101 Switching Protocols
2XX(成功) 200(成功)、201(服务器创建)、202(服务器接收未处理)、203(非授权信息)、204(未返回内容)、205(重置内容)、206(部分内容)
3XX(重定向) 301(永久移动)、302(临时移动)、303(查看其他位置)、304(未修改)、305(使用代理)、307(临时重定向)
4XX(客户端错误) 400(错误请求)、401(未授权)、403(禁止)、404(未找到)、405(方法禁用)、406(不接受)、407(需要代理授权)
5XX(服务器错误) 500(服务器异常)、501(尚未实施)、502(错误网关)、503(服务不可用)、504(网关超时)、505(HTTP 版本不受支持)

总括

  • 1xx:指示信息–表示请求已接收,继续处理。
  • 2xx:指示成功–表示请求已被成功接收、理解、接受。
  • 3xx:指示重定向–要完成请求必须进行更进一步的操作。
  • 4xx:指示客户端错误–请求有语法错误或请求无法实现。
  • 5xx:指示服务器端错误–服务器未能实现合法的请求。

# 缓存分类

# 按协议分

协议层缓存和非 http 协议缓存

非协议层缓存:利用 meta 标签的 http-equiv 属性值 Expires,set-cookie协议层缓存:利用 http 协议头属性值设置;

# 按缓存分

强缓存和协商缓存

强缓存:利用 cache-control 和 expires 设置,直接返回一个过期时间,所以在缓存期间不请求,If-modify-since; 协商缓存:响应头返回 etag 或 last-modified 的哈希值,第二次请求头 If-none-match 或 IF-modify-since 携带上次哈希值,一致则返回 304。

类型 特性
强缓存 通过 If-modify-since(last-modify)、expires 和 cache-control 设置,属性值是时间,所以在时间内不用请求
协商缓存 通过 If-none-match(etag)设置,etag 属性是哈希值,所以要请求和服务器值对比
# 缓存比较

强制缓存的优先级高于协商缓存,当执行强制缓存时,如若缓存命中,则直接使用缓存数据库数据,不在进行缓存协商。

协商缓存对比: etag 优先级高于 last-modified; etag 精度高,last-modified 精度是 s,1s 内 etag 修改多少次都会被记录; last-modified 性能好,etag 要得到 hash 值。

如果不是强制刷新,而且请求头带上了if-modified-since和if-none-match两个字段,则先判断etag,再判断last-modified。

# 校验过期机制
  • 校验是否过期: Expires, Cache-Control(max-age)
  • 协议Etag头信息校验; Etag
  • 协议中Last-Modified头信息校验;Last-Modified

# CSS基础

# 布局相关设置【PDFOZ】

# display的设置

单位 描述
none 元素不显示,并从文档流中移除。
block 块类型。默认宽度为父元素宽度,可设置宽高,换行显示。
inline 行内元素类型。默认宽度为内容宽度,不可设置宽高,同行显示。
inline-block 默认宽度为内容宽度,可以设置宽高,同行显示。
inherit 规定应该从父元素继承 display 属性的值。
table 此元素会作为块级表格来显示。表格显示;
list-item 象块类型元素一样显示,并添加样式列表标记。项目列表;
/*==display 显示属性(div与span的区别); 反过来设置==*/
.div_span_1_cls,.div_span_2_cls,.div_span_3_cls{
  background: green;
  display: inline;
}
span{
  background-color: red;
  display: block;
  width: 200px;
}
<div class="div_span_1_cls">Samy张</div>
<div class="div_span_2_cls">Samy张</div>
<div class="div_span_3_cls">Samy张</div>
<span class="span_div_3_cls">Samy张S</span>
<span class="span_div_3_cls">Samy张S</span>
<span class="span_div_3_cls">Samy张S</span>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# position 定位方式

设置

  • static 默认值。没有定位,元素出现在正常的流中(忽略 top, bottom, left, right z-index 声明)。
  • relative 生成相对定位的元素,相对于其正常位置进行定位。
  • absolute 生成绝对定位的元素,相对于值不为 static的第一个父元素进行定位。 fixed也可以;
  • fixed 生成绝对定位的元素,相对于浏览器窗口进行定位 ;悬浮设置后,宽高会自适应,记得设置 width: 100%,及定位设置;一个固定定位元素不会保留它原本在页面应有的空隙。(老IE不支持)
  • inherit 继承; 规定从父元素继承 position 属性的值。

定位: left(左),right(右),top(上),bottom(下)离页面顶点的距离

绝对定位和fixed定位的比较

共同点:改变行内元素的呈现方式,都脱离了文档流

不同点:absolute的**”根元素“是可以设置的,fixed的“根元素”固定为浏览器窗口**

position: absolute;

  • 相对于 非static的先辈元素定位;(正常情况); 相对于最近的已定位的祖先元素, 有已定位(指position不是static的元素)祖先元素, 以最近的祖先元素为参考标准。如果无已定位祖先元素, 以body元素为偏移参照基准, 完全脱离了标准文档流。
  • 如果先辈元素全是static,那么相对于视口定位;(特殊情况)

position:fixed

  • 相对于视口定位;(正常情况)
  • 如果先辈元素有 非nonetransform属性,那么相对于该先辈元素定位(不注意容易产生BUG)

失效的解决办法是:对父级元素设置transform: none; 或者display:inline

# position:fixed;在android下无效怎么处理?

手机上兼容设置:所以说并不是iOS不支持fixed,只是fixed的元素不是相对手机屏幕固定的

通过以下设置处理:

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no"/>
1

# float 浮动属性

left 左浮动 right 右浮动 clear 清除浮动; clear:both

注:设置 Flex 布局后,子元素的 Float 布局将失效

# overflow 溢出处理

hidden 隐藏超出层大小的内容 ​ scroll 无论内容是否超出层大小都添加滚动条 ​ auto 超出时自动添加滚动条

# margin 属性

  • margin 属性为给定元素设置所有四个(上左下右)方向的外边距属性。

  • 普通元素的 百分比margin 都是相对于容器的宽度计算的

  • 绝对定位元素的 百分比margin 相对于其定位祖先元素的宽度计算的

  • 上下margin会重叠:只会发生在 block元素上,(取最大值)

    解决重叠方法:

    1. 父元素设置 BFC(如overflow:hidden;如position:absolute等)
    2. 父元素设置 border/padding
  • 当 margin 的值为 auto时。浏览器会自动选择一个合适的margin来应用(自动分配剩余空间)

    1. 需要元素是 块状元素
    2. 需要元素 设置宽度
  • margin 可以为 负值

# z-index网页的层叠等级

z-index 层覆盖先后顺序(优先级); 大于0的数字;数字大的最上面

其实一个网页是分为好多层的,具体层次和层叠等级如下图:

z-index为正值 》 z-index: 0/auto 》 行内元素 》 浮动元素 》 块级元素 》z-index为负数 》 background/border

# 设置DOM元素不显示在浏览器可视范围内

# visibility:hidden/visible、display:none、z-index=-1、opacity:0 及比较;【OVDZ】

  1. opacity:0,该元素隐藏起来了,但不会改变页面布局,并且,如果该元素已经绑定了一些事件,如click事件也能触发
  2. visibility:hidden,该元素隐藏起来了,但不会改变页面布局,但是不会触发该元素已经绑定的事件; (重绘)
  3. display:none, 把元素隐藏起来,并且会改变页面布局,可以理解成在页面中把该元素删掉; (回流+重绘)
  4. z-index=-1置于其他元素下面; 注意:z-index的数值不跟单位。z-index的数字越高越靠前,并且值必须为整数和正数(正数的整数)。

总括

最基本的:设置visibility属性为hidden,或者设置display属性为none

技巧性:设置透明度为0,设置z-index位置在-1000, 设置宽高为0

1. display:none;

  • DOM结构:浏览器不会渲染display属性为none的元素,不占据空间,意思就是页面上没有它的一席之地,你在开发者模式中选不中那个元素。
  • 事件监听:无法进行DOM事件监听。
  • 性能:动态改变此属性时会引起重排,性能较差。
  • 继承:不会被子元素继承,因为子元素也不被渲染。
  • transtion过渡不支持display。

2. visibility:hidden;

  • DOM结构:元素被隐藏了,浏览器会渲染visibility属性为hidden的元素,占据空间,意思就是页面上有它的空间,在开发者模式中能选中那个元素。
  • 事件监听:无法进行DOM事件监听。
  • 性能:动态改变此属性时会引起重绘,性能较高。
  • 继承:会被子元素继承,子元素通过设置visibility:visible;来显示自身,使子元素取消自身隐藏。
  • transtion:visibility会立即显示,隐藏时会延时。

3. opacity:0;

  • DOM结构:opacity属性值为0时透明度为100%,元素隐藏,占据空间,opacity值为0到1,为1时显示元素。
  • 事件监听:可以进行DOM事件监听。
  • 性能:提升为合成层,不会引发重绘,性能较高。
  • 继承:会被子元素继承,子元素不能通过设置opacity:1;来取消隐藏。。
  • transtion:opacity可以延时显示与隐藏。

# 行内(inline)/块级(block)/空(void)元素

首先:CSS规范规定,每个元素都有display属性,确定该元素的类型,每个元素都有默认的display值

如span默认display属性值为“inline”,是“行内”元素; div的display默认值为“block”,则为“块级”元素;

行内(inline)元素宽度和高度由内容决定与其他元素共占一行的元素; 内边距的top/bottom(padding-top/padding-bottom)和外边距的top/bottom(margin-top/margin-bottom)都不可改变(也就是padding和margin的left和right是可以设置的),就是里面文字或图片的大小。

​ 如:i a b span select strong

块级(block)元素默认宽度由父容器决定,默认高度由内容决定独占一行并且可以设置宽高的元素;

​ 如:div ul ol li dl dt dd h1 h2 h3 h4…p

浏览器还有默认的天生inline-block【空】元素(拥有内在尺寸,可设置高宽,但不会自动换行

​ 如:<input> 、<img> 、<button> 、<texterea> 、<label>

在日常开发中,经常使用 CSS 的 display 属性来打破两者的壁垒:display: inline-block,使它们拥有更多的状态。常见的空元素: 不同浏览器(版本)、HTML4(5)、CSS2等实际略有差异;

<br> <hr> <img> <input> <link> <meta>
//鲜为人知的是:
<area> <base> <col> <command> <embed> <keygen> <param> <source> <track> <wbr>
1
2
3

说明

  • 块级标签可以设置width和height
  • 行内标签不可以设置width和height它的width由内容决定,height由font-size决定
  • block水平的元素inline-block化后,IE6/7没有换行符间隙问题,其他浏览器均有;{ display: inline-block; *display: inline; *zoom: 1; } inline水平的元素inline-block后,所有主流浏览器都有换行符/空格间隙问题

# Flex 布局

Flex 是 Flexible Box 的缩写,意为”弹性布局”,用来为盒状模型提供最大的灵活性

行内元素也可以使用 Flex 布局。display: inline-flex;Webkit 内核的浏览器,必须加上-webkit前缀。display: -webkit-flex; /* Safari */

注意,设为 Flex 布局以后,子元素的float、clear和vertical-align属性将失效

# 父元素属性(6个)

属性名 属性值 备注
display flex 定义了一个flex容器,它的直接子元素会接受这个flex环境
flex-direction row,row-reverse,column,column-reverse 决定主轴的方向
flex-wrap nowrap,wrap,wrap-reverse 如果一条轴线排不下,如何换行
flex-flow [flex-direction] , [flex-wrap] flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap
justify-content flex-start,flex-end,center,space-between,space-around 设置或检索弹性盒子元素在主轴(横轴)方向上的对齐方式
align-items flex-start,flex-end,center,baseline,stretch 设置或检索弹性盒子元素在侧轴(纵轴)方向上的对齐方式

# 子元素属性(6个)

属性名 属性值 备注
order [int] 默认情况下flex order会按照书写顺训呈现,可以通过order属性改变,数值小的在前面,还可以是负数。
flex-grow [number] 设置或检索弹性盒的扩展比率,根据弹性盒子元素所设置的扩展因子作为比率来分配剩余空间
flex-shrink [number] 设置或检索弹性盒的收缩比率,根据弹性盒子元素所设置的收缩因子作为比率来收缩空间
flex-basis [length], auto 设置或检索弹性盒伸缩基准值
align-self auto,flex-start,flex-end,center,baseline,stretch 设置或检索弹性盒子元素在侧轴(纵轴)方向上的对齐方式,可以覆盖父容器align-items的设置
flex [number] 占比

# ES基础

# 基本类型及判断方式

# 【SSBNNU】 S

# 基本数据类型

Symbol(ES6)、String、Boolean、Number、Null、Undefined; 简写:SSBNNU 栈(stack)

# 内置对象

Object 是 JavaScript 中所有对象的父对象

数据封装类对象:Object、Array、Boolean、Number 和 String

其他对象:Function、Arguments、Math、Date、RegExp、Error

# 判断方式对比

  • ===能用于判断null和undefined,因为这两种类型的值都是唯一的

    undefined === null; // false,类型不相同
    undefined !== null;  // true, 类型不相同
    
    1
    2
  • typeof返回一个表示数据类型的字符串,返回结果包括:number、boolean、string、symbol、object、undefined、function等7种数据类型,*但不能判断null、array、object等,*但是 typeof null === 'object';

  • instanceof 运算符用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性但它不能检测null 和 undefined; 基础类型没有 __proto__

  • **constructor作用和instanceof非常相似。**但constructor检测 Object与instanceof不一样,还可以处理基本数据类型的检测但它不能检测null 和 undefined

    const targetObj = source.constructor === Array ? [] : {}; // 判断复制的目标是数组还是对象

  • Object.prototype.toString.call() 最准确最常用的方式;

    toString() 是 Object 的原型方法,调用该方法,默认返回当前对象的 [[Class]] 。这是一个内部属性,其格式为 [object Xxx] ,其中 Xxx 就是对象的类型。

    对于 Object 对象,直接调用 toString() 就能返回 [object Object] 。而对于其他对象,则需要通过 call / apply 来调用才能返回正确的类型信息。

及ES6新加入的方法Array.isArray():检测某个值是否为数组(ES6)

# instanceOf原理

# 对象的深拷贝操作比较

//定义检测数据类型的功能函数 
function checkedType(target) { 
	return Object.prototype.toString.call(target).slice(8, -1) //获取从第九个到倒数第二个字符
}//targetType ==='Object'; 比如[object String]获取 String

function simpleClone(obj) {//浅拷贝
  let newObj = {};
  for (let i in obj) {
    newObj[i] = obj[i];
  }
  return newObj;
}
//方式一:直接用instancof/typeof判断;【推荐】简洁;
function deepClone(obj){
  var newObj= obj instanceof Array?[]:{};
  for(var i in obj){
    newObj[i]=typeof obj[i]=='object'? deepClone(obj[i]):obj[i]; 
  }
  return newObj;
} 
function deepClone(obj) {//第二种方式;跟方式一类似;
  let result;
  if (typeof obj == 'object') {
    result = isArray(obj) ? [] : {}
    for (let i in obj) {
      result[i] = isObject(obj[i])||isArray(obj[i])?deepClone(obj[i]):obj[i]
    }
  } else {
    result = obj
  }
  return result
}
function isObject(obj) {
  return Object.prototype.toString.call(obj) == "[object Object]"
}
function isArray(obj) {
  return Object.prototype.toString.call(obj) == "[object Array]"
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

# 隐藏转换

所有对象都有valueOf方法,valueOf方法对于:如果存在任意原始值,它就默认将对象转换为表示它的原始值。

类型先通过 valueOftoString 进行隐式转换;

let a = {
  value: 0,
  valueOf: function() {
    this.value++;
    return this.value;
  }
};
console.log(a == 1 && a == 2);
1
2
3
4
5
6
7
8

# 数组

# for循环

  • 简单for
  • 循环for-in(最慢):**循环遍历的是对象的属性,而不是数组的索引。**因此, for-in 遍历的对象便不局限于数组,还可以遍历对象。
  • forEach(最快):没有返回值; a.forEach(function(item, idx, arr){})
  • map有返回值
  • for-of(ES6+):
# 方法及比较
  • forEach/map 不能 break 和 return;

  • for-in 缺点更加明显,它不仅遍历数组中的元素,还会遍历自定义的属性,甚至原型链上的属性都被访问到。而且,遍历数组元素的顺序可能是随机的。 for in更适合遍历对象;

  • for-of优点:推荐

    • 跟 forEach 相比,可以正确响应 break, continue, return。
    • for-of 循环不仅支持数组,还支持大多数类数组对象,例如 DOM nodelist 对象。
    • 其不仅可以遍历数组,还可以遍历类数组对象和其他可迭代对象。
    • for-of 循环也支持字符串遍历,它将字符串视为一系列 Unicode 字符来进行遍历。
    • for-of 也支持 Map 和 Set (两者均为 ES6 中新增的类型)对象遍历。

# forEach 、for in、 for of各自的特点是什么?

  1. forEach 只能遍历数组,且不能中断(break等无效); 可查看后面forEach内部源码的实现;
  2. for in 遍历的是对象的可枚举属性;结合hasOwnPropery方法可以判断某属性是否是该对象的实例属性;
  3. for of 遍历的是对象的迭代器属性;

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

for of遍历的只是数组内的元素,而不包括数组的原型属性method和索引name

# 常用方法

栈方法 push() 可以接收任意数量的参数,把他们逐个添加到数组的末尾,返回修改后数组的长度 pop() 从数组末尾移除最后一项,返回移除的项 队列方法 unshift() 向数组前端添加任意个项并返回新数组的长度 shift() 移除数组的第一项并返回该项 排序 sort(compare): compare函数接收两个参数,如果返回负数,则第一个参数位于第二个参数前面;如果返回零,则两个参数相等;如果返回正数,第一个参数位于第二个参数后面; (a,b) => (b-a) // 降序,升序相反 Array.sort();如果不带参数调用sort,数组以字母顺序进行排序升序; 如果数组中包含undefined元素,它们会被排到数组的尾部

操作方法 concat(数组 | 一个或多个元素) ;合并数组,返回新数组 slice(起始位置 ,[结束位置]);切分数组,返回新数组,新数组不包含结束位置的项 splice(起始位置,删除的个数,[插入的元素]) // 删除|插入|替换数组,返回删除的元素组成的数组,会修改原数组 reverse(): 反转数组元素的顺序 Array.join()是Array.split()方法的逆向操作;以指定分隔符连接,如果不指定,默认以,连接; Array.toString(): 返回一个字符串,表示指定的数组及其元素。跟join类似;

# 其他遍历相关方法

some()、every()、filter()、map()、forEach()都是对数组的每一项调用函数进行处理。

– some()、every()的返回值 :true / false

– filter()、map()的返回值 :一个新数组

– forEach()无返回值。当然forEach也可以改变原数组:return

使用some()、every()、filter()、map()、forEach()都不改变原数组

find返回通过指定条件(函数内判断)的数组的第一个元素的值; 不创建新数组

arr.filter()、includes()、find()、findIndex(); indexOf(), lastIndexOf()//方法对大小写敏感

# 归并方法: reduce/reduceRight

对数组中的元素依次处理,将上次结果作为下次处理的输入,最后得到最终结果。接收一个函数作为累加器;

数组只有一项或是个空数组不做遍历操作; 如果归并的数组为空,则会报错;

# 遍历方法类似原理

# foreach的类似实现原理
// if (!Array.prototype.forEach) {
Array.prototype.forEach = function(fn) {
  for (var i = 0; i < this.length; i++) {
    fn(this[i], i, this);
  }
};
// }
["a", "b", "c"].forEach(function(value, index, array) {
  console.log((value, "Is in position " + index + " out of " + (array.length - 1)));
});
1
2
3
4
5
6
7
8
9
10

# 常用算法

# 合并

1.终极篇

[1,2,3,4].concat([5,6]) //[1,2,3,4,5,6]
[...[1,2,3,4],...[4,5]] //[1,2,3,4,5,6]
let arrA = [1, 2], arrB = [3, 4]
Array.prototype.push.apply(arrA, arrB))//arrA值为[1,2,3,4]
1
2
3
4

2.开始篇

let arr=[1,2,3,4];
 [5,6].map(item=>{
   arr.push(item)
 })
 //arr值为[1,2,3,4,5,6],注意不能直接return出来,return后只会返回[5,6]
1
2
3
4
5
# 判断是否包含值

1.终极篇

[1,2,3].includes(4) //false
[1,2,3].indexOf(4) //-1 如果存在换回索引
[1, 2, 3].find((item)=>item===3)) //3 如果数组中无值返回undefined
[1, 2, 3].findIndex((item)=>item===3)) //2 如果数组中无值返回-1
1
2
3
4

includes(),find(),findIndex()是 ES6的api

2.开始篇

[1,2,3].some(item=>{
  return item===3
}) //true 如果不包含返回false
1
2
3
# 最大值
var arr = [1, 2, 3, 4];
console.log(Math.max(...arr)); //4
console.log(Math.max.call(this, 1, 2, 3, 4))
console.log(Math.max.call(this, ...arr)); //4
console.log(Math.max.apply(this, arr)); //4
console.log(
  arr.reduce((prev, cur, curIndex, arr) => {
    return Math.max(prev, cur);
  }, 0)
); //4

//两个功能是一样的;比如:func是Math.max的话;
//return func(..._args);
//return func.apply(null, _args);
1
2
3
4
5
6
7
8
9
10
11
12
13
14

Math.max()是Math对象内置的方法,参数是字符串;

# 求两数组中不同元素
const arr1 = [1,2,3,4,5]
const arr2 = [2,3,1,0,5]
const ans = arr1.filter(v => arr2.indexOf(v) == -1 )//[4]

const a = new Set(arr1) const b = new Set(arr2)
new Set([...a, ...b])//并集  
new Set([...a].filter(v => b.has(v)))//交集  
new Set([...a].filter(v => !b.has(v)))//差集
1
2
3
4
5
6
7
8

# 原型链

# 类/TS

# 异步

# VUE

# 生命周期

# 各个生命周期及描述 (8+2)

生命周期 描述
beforeCreate 组件实例被创建之初,组件的属性生效之前;vue实例的挂载元素$el和数据对象 data都是undefined, 还未初始化
created 组件实例已经完全创建,属性也绑定,完成了 data数据初始化;但真实 dom 还没有生成,$el 还不可用
beforeMount 在挂载开始之前被调用:相关的 render 函数首次被调用;vue实例的$el和data都初始化了
mounted el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子;在 mounted 被调用前,Vue 已经将编译好的模板挂载到页面上,所以在 mounted 中可以访问操作 DOM
beforeUpdate 组件数据更新之前调用,发生在虚拟 DOM 打补丁之前
update 组件数据更新之后
activited keep-alive 专属,组件被激活时调用
deactivated keep-alive 专属,组件被销毁时调用
beforeDestory 组件销毁前调用
destoryed 组件销毁后调用

官方版本

# 生命周期总括【要点】

8 个生命周期,创建前/创建后、挂载前/挂载后、更新前/更新后、销毁前/销毁后。Vue 生命周期的作用方便我们通过它的生命周期,在业务代码中更好地操作数据,实现相关功能。这些函数称为生命周期 hook

8个生命周期过程:Vue 实例(组件)从其初始化到销毁和删除都经历生命周期;

  1. 创建前/后
    • beforeCreated 阶段,Vue 实例的挂载元素 $el 和数据对象 data 以及事件还未初始化。
    • created 阶段,Vue 实例的数据对象 data 以及方法的运算有了,$el 还没有。
  2. 载入前/后
    • beforeMount 阶段,render 函数首次被调用,Vue 实例的 $el 和 data 都初始化了,但还是挂载在虚拟的 DOM 节点上
    • mounted 阶段,Vue 实例挂载到实际的 DOM 操作完成,一般在该过程进行 Ajax 交互
  3. 更新前/后
    • 在数据更新之前调用,即发生在虚拟 DOM 重新渲染和打补丁之前,调用 beforeUpdate
    • 在虚拟 DOM 重新渲染和打补丁之后,会触发 updated 方法。
  4. 销毁前/后
    • 在执行实例销毁之前调用 beforeDestory,此时实例仍然可以调用
    • 在执行 destroy 方法后,对 data 的改变不会再触发周期函数,说明此时 Vue 实例已经解除了事件监听以及和 DOM 的绑定,但是 DOM 结构依然存在

# watch、computed与methods的联系和区别【要点】

watch 就是监听的意思,其专门用来观察和响应Vue实例上的数据的变动

能使用watch属性的场景基本上都可以使用computed属性,而且computed属性开销小,性能高,因此能使用computed就尽量使用computed属性

想要执行异步或昂贵的操作以响应不断变化的数据时,这时watch就派上了大用场。

其应用场景一般都是搜索框之类的,需要不断的响应数据的变化;如果要在数据变化的同时进行异步操作或者是比较大的开销,那么watch为最佳选择。

computed 就是计算属性,其可以当成一个data数据来使用。直接使用,不用像方法那样调用();

# v-ifv-show指令

  • v-if指令是直接销毁和重建DOM达到让元素显示和隐藏的效果; 每次显示状态更改时,代价通常会更大。

  • v-show指令是通过修改元素的display CSS属性(display:none)让其显示或者隐藏; 但是display:none, 把元素隐藏起来,并且会改变页面布局

  • 一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,

    • 如果需要非常频繁地切换,则使用 v-show 较好
    • 如果在运行时条件很少改变,则使用 v-if 较好

    总括

    另一方面,v-show 成本较低,因为它仅切换元素的CSS显示属性。所以如果必须经常切换元素,则 v-show 会提供比 v-if 更好,更优化的结果。

    就加载元素的初始渲染成本而言,v-if 不会渲染最初隐藏的元素的节点,而 v-show 会渲染其 CSS display 属性被设置为 none 的元素

# v-ifv-for指令

不推荐同时使用 v-ifv-for; 当 v-ifv-for 一起使用时,v-for 具有比 v-if 更高的优先级。这意味着 v-if 将分别重复运行于每个 v-for 循环中。

v-for 比 v-if 优先级高,如果每一次都需要遍历整个数组,将会影响速度,尤其是当之需要渲染很小一部分的时候,必要情况下应该替换成 computed 属性

# vue中常用的命令

  • v-if/v-show区别 判断是否隐藏
  • v-for 数据循环出来
  • v-model 实现双向绑定
  • v-bind v-bind:class:绑定一个属性;
  • v-on

# 更新检测

# 数组更新检测 vm.$set

由于 JavaScript 的限制,Vue 不能检测以下数组的变动:

  1. 当你利用索引直接设置一个数组项时,例如:vm.items[indexOfItem] = newValue
  2. 当你修改数组的长度时,例如:vm.items.length = newLength

解决办法

解决上面1问题: Vue 提供了以下操作方法:

Vue.set(vm.items, indexOfItem, newValue)// Vue.set
vm.$set(vm.items, indexOfItem, newValue)// vm.$set,Vue.set的一个别名
vm.items.splice(indexOfItem, 1, newValue)// Array.prototype.splice; 底层实现方式;
1
2
3

解决上面2问题:Vue 提供了以下操作方法:

vm.items.splice(newLength)// Array.prototype.splice
1

示例:通过socket监听设备在线状态

sockets: {
    sDevices: function (value) {
        const index = this.data.findIndex(item => value.id === item.id)
        if (index >= 0) {
            this.data.splice(index, 1, value)
        }
    }
},
1
2
3
4
5
6
7
8

# 对象更新检测

还是由于 JavaScript 的限制,Vue 不能检测对象属性的添加或删除

对于已经创建的实例,Vue 不允许动态添加根级别的响应式属性。但是,可以使用Vue.set (object, propertyName, value) / vm.$set (object, propertyName, value) 来实现为对象添加响应式属性

# Vue 组件间通信几种方式【要点】

Vue 组件间通信只要指以下 3 类通信:父子组件通信、隔代组件通信、兄弟组件通信

总括:常用的三种: props / $emit, EventBus ($emit / $on), Vuex ;

# 监听子组件事件

# $emit

【父集监听:v-on:xx="postFontSize += 0.1"; 子集发送:v-on:click="$emit('xx')"

v-on:input="$emit('input', $event.target.value)" 详细可见自定义事件;

# Vuex/Router

# Vuex几个核心模块【要点】

vuex主要由五部分组成:state、 getters、mutations、actions、module组成。

主要包括以下几个模块:(sgmam) + mapG amsg m

  • State:定义了应用状态的数据结构,可以在这里设置默认的初始状态
  • Getter:允许组件从 Store 中获取数据,mapGetters 辅助函数仅仅是将 store 中的 getter 映射到局部计算属性
  • Mutation:是唯一更改 store 中状态的方法,且必须是同步函数
  • Action:用于提交 mutation,而不是直接变更状态,可以包含任意异步操作
  • Module:允许将单一的 Store 拆分为多个 store 且同时保存在单一的状态树中

使用流程是: 组件中可以直接调用上面五个部分除了module; Vuex 适用于 父子、隔代、兄弟组件通信

组件不允许直接修改属于 store 实例的 state,而应执行 action 来分发 (dispatch) 事件通知 store 去改变,我们最终达成了 Flux (opens new window) 架构。这样约定的好处是,我们能够记录所有 store 中发生的 state 改变,同时实现能做到记录变更 (mutation)、保存状态快照、历史回滚/时光旅行的先进的调试工具

应用级的状态集中放在store中; 改变状态的方式是提交mutations,这是个同步的事务异步逻辑应该封装在action中

# HTML5 History 模式

vue-router 默认 hash 模式 —— 使用 URL 的 hash 来模拟一个完整的 URL,于是当 URL 改变时,页面不会重新加载。

如果不想要很丑的 hash,我们可以用路由的 history 模式,这种模式充分利用 history.pushState API 来完成 URL 跳转而无须重新加载页面

const router = new VueRouter({
  mode: 'history',
  routes: [...]
})
1
2
3
4

当你使用 history 模式时,URL 就像正常的 url,例如 http://yoursite.com/user/id,也好看!

不过这种模式要玩好,还需要后台配置支持。因为我们的应用是个单页客户端应用,如果后台没有正确的配置,当用户在浏览器直接访问 http://oursite.com/user/id 就会返回 404,这就不好看了。

# 后端配置

nginx 常用; try_files $uri $uri/ /index.html;

你也许注意到 router.pushrouter.replacerouter.gowindow.history.pushStatewindow.history.replaceStatewindow.history.go类似;

# hash 模式和 history 模式的区别【要点】

  • url 展示上,hash 模式有“#”,history 模式没有
  • 刷新页面时,hash 模式可以正常加载到 hash 值对应的页面,而 history 没有处理的话,会返回 404,一般需要后端将所有页面都配置重定向到首页路由try_files $uri $uri/ /index.html;
  • 兼容性。hash 可以支持低版本浏览器和 IE。

# React

# 生命周期

# 图示

React 16.3 版本之前 生命周期

react生命周期old

React 新版 生命周期

react生命周期new

# Webpack

# 其他

Nginx

node 工具脚手架

# 沟通

# 职业发展

上次更新: 2022/04/15, 05:41:33
×