2022前端面试题

---CSS/HTML部分---

这部分可能会先问你css3和html5都增加了那些新元素,然后扩展着问

0、css布局方式

1、table布局(现在少用)

2、flex布局

3、float布局

4、响应式布局

1、说一下盒子模型(常问)

标准盒模型和IE盒子模型

这两个的区别主要是

IE盒子模型的宽高包括content和padding还有border,标准盒子模型 不包括,

box-sizing:content-box 标准盒模型

box-sizing:border-box IE盒模型

2、Html5新标签

canvas 新元素

新多媒体元素

新的语义和结构元素

HTML5提供了新的元素来创建更好的页面结构:

3、BFC

BFC(Block Formatting Context),即块级格式化上下文,它是页面中一个独立的容器,容器中的元素不会影响到外面的元素

触发条件

触发BFC的条件包含不限于:

  • 根元素,即HTML元素
  • 浮动元素:float值为left、right
  • overflow值不为 visible,为 auto、scroll、hidden
  • display的值为inline-block、inltable-cell、table-caption、table、inline-table、flex、inline-flex、grid、inline-grid
  • position的值为absolute或fixed

4、浏览器运行机制

1、创建DOM树

2、构建渲染树,CSS渲染

3、布局渲染,每个元素的大小、位置

4、绘制渲染树、再画出来

重绘:改变元素的外观属性例如div的color、background-color、等属性发生改变时

重排(回流):元素的规模尺寸、布局、隐藏改变时

代价:耗时,导致浏览器卡慢

5、居中的方式

垂直居中的方式

行高=高

绝对定位 top50%,自身宽度的50%的负值

flex布局 align---center

水平居中的方式

绝对定位

flex布局 juest---center

text-align center

6、rem、em、vh、px各自代表的含义?

px:绝对单位,页面按精确像素展示

em:相对单位,基准点为父节点字体的大小,如果自身定义了font-size按自身来计算,整个页面内1em不是一个固定的值

rem:相对单位,可理解为root em, 相对根节点html的字体大小来计算

vh、vw:主要用于页面视口大小布局,在页面布局上更加方便简单

7、有哪些方式可以隐藏页面元素?区别?

通过css实现隐藏元素方法有如下:

  • display:none
  • visibility:hidden
  • opacity:0
  • 设置height、width模型属性为0
  • position:absolute
  • clip-path

关于display: nonevisibility: hiddenopacity: 0的区别,如下表所示:

8、什么是响应式设计?响应式设计的基本原理是什么?如何做?

响应式网站设计(Responsive Web design)是一种网络页面设计布局,页面的设计与开发应当根据用户行为以及设备环境(系统平台、屏幕尺寸、屏幕定向等)进行相应的响应和调整

响应式网站常见特点:

  • 同时适配PC + 平板 + 手机等
  • 标签导航在接近手持终端设备时改变为经典的抽屉式导航
  • 网站的布局会根据视口来调整模块的大小和位置

实现响应式布局的方式有如下:

  • 媒体查询(我们可以设置不同类型的媒体条件,并根据对应的条件,给相应符合条件的媒体调用相对应的样式表)
  • 百分比
  • vw/vh
  • rem

响应式设计实现通常会从以下几方面思考:

  • 弹性盒子(包括图片、表格、视频)和媒体查询等技术
  • 使用百分比布局创建流式布局的弹性UI,同时使用媒体查询限制元素的尺寸和内容变更范围
  • 使用相对单位使得内容自适应调节
  • 选择断点,针对不同断点实现不同布局和内容展示

9、css选择器有哪些?优先级?

关于css属性选择器常用的有:

  • id选择器(#box),选择id为box的元素
  • 类选择器(.one),选择类名为one的所有元素
  • 标签选择器(div),选择标签为div的所有元素
  • 后代选择器(#box div),选择id为box元素内部所有的div元素
  • 子选择器(.one>one_1),选择父元素为.one的所有.one_1的元素
  • 相邻同胞选择器(.one+.two),选择紧接在.one之后的所有.two元素
  • 群组选择器(div,p),选择div、p的所有元素

还有一些使用频率相对没那么多的选择器:

  • 伪类选择器
:link 选择未被访问的链接
:visited选取已被访问的链接
:active选择活动链接
:hover 鼠标指针浮动在上面的元素
:focus 选择具有焦点的
:first-child父元素的首个子元素
  • 伪元素选择器
:first-letter 用于选取指定选择器的首字母
:first-line 选取指定选择器的首行
:before : 选择器在被选元素的内容前面插入内容
:after : 选择器在被选元素的内容后面插入内容
  • 属性选择器
[attribute] 选择带有attribute属性的元素
[attribute=value] 选择所有使用attribute=value的元素
[attribute~=value] 选择attribute属性包含value的元素
[attribute|=value]选择attribute属性以value开头的元素

CSS3中新增的选择器有如下:

  • 层次选择器(p~ul),选择前面有p元素的每个ul元素
  • 伪类选择器
:first-of-type 父元素的首个元素
:last-of-type 父元素的最后一个元素
:only-of-type 父元素的特定类型的唯一子元素
:only-child 父元素中唯一子元素
:nth-child(n) 选择父元素中第N个子元素
:nth-last-of-type(n) 选择父元素中第N个子元素从后往前
:last-child 父元素的最后一个元素
:root 设置HTML文档
:empty 指定空的元素
:enabled 选择被禁用元素
:disabled 选择被禁用元素
:checked 选择选中的元素
:not(selector) 选择非 <selector> 元素的所有元素
  • 属性选择器
[attribute*=value]选择attribute属性值包含value的所有元素
[attribute^=value]选择attribute属性开头为value的所有元素
[attribute$=value]选择attribute属性结尾为value的所有元素

优先级

内联 > ID选择器 > 类选择器 > 标签选择器

10、清除浮动的方法

方法一:使用带 clear 属性的空元素

在浮动元素后使用一个空元素,并在 CSS 中赋 予.clear{clear:both;}属性即可清理浮动。

方法二:使用 CSS 的 overflow 属性

给浮动元素的容器添加 overflow:hidden;或 overflow:auto;可以清除浮动,另外在 IE6 中还 需要触发 hasLayout ,例如为父元素设置容器宽高或设置 zoom:1。 在添加 overflow 属性后,浮动元素又回到了容器层,把容器高度撑起,达到了清理浮动 的效果。

方法三:给浮动的元素的容器添加浮动

给浮动元素的容器也添加上浮动属性即可清除内部浮动,但是这样会使其整体浮动,影 响布局,不推荐使用。

方法四:使用 CSS 的:after 伪元素

结合:after 伪元素(注意这不是伪类,而是伪元素,代表一个元素之后最近的元素)和 IEhack ,可以完美兼容当前主流的各大浏览器,这里的 IEhack 指的是触发 hasLayout。 给浮动元素的容器添加一个 clearfix 的 class,然后给这个 class 添加一个:after 伪元素实 现元素末尾添加一个看不见的块元素清除浮动

 

11、常见的行内元素、块级元素

1、块级元素(div,p,h1...h6,ol,ul,table)

每个块级元素都是独自占一行、元素的高度宽度都是可以设置的

2、行内元素(span,a,img,input,strong)

可以和其他元素处于一行上,元素的高度宽度顶部和底部边距不可设置

12、position的属性

此处,问过相对定位和绝对定位的区别

相对定位:相对于当前元素的位子来移动;绝对定位如果不把父元素设置为相对定位,则相对与页面的左上角定位

13. 谈谈做好seo需要考虑什么?

  • 语义化html标签
  • 合理的title, description, keywords;
  • 重要的html代码放前面
  • 少用iframe, 搜索引擎不会抓取iframe中的内容
  • 图片加上alt

**---JavaScript部分---**

0、ES6新增了哪些方法

1、includes()用于判断数组是否包含给定的值 返回一个布尔值

2、find()用于找出第一个符合条件的数组成员

3、findindex()返回第一个符合条件的数组成员的位置,如果所有成员都不符合条件,则返回-1

4、set数据结构,类似于数组,但是成员的值都是唯一的,没有重复的值

5、、let声明变量、const声明常量(这里就要问你var、let、const的区别了)

6、解构赋值 ...

set 和map 的区别!!!以前被问没看过,懵逼过,所以要记住

1.Map是键值对,Set是值的集合,键和值可以是任何的值;

2.Map可以通过get方法获取值,而set不能因为它只有值,set只能用has来判断,返回一个布尔值;

4.Set的值是唯一的可以做数组去重,Map由于没有格式限制,可以做数据存储

 

1、promiseApi

Promise构建出来的实例存在以下方法:

  • then() 是实例状态发生改变时的回调函数,第一个参数是resolved状态的回调函数,第二个参数是rejected状态的回调函数
  • catch() 用于指定发生错误时的回调函数
  • finally() 用于指定不管 Promise 对象最后状态如何,都会执行的操作

Promise构造函数存在以下方法:

  • all() 用于将多个 Promise实例,包装成一个新的 Promise实例
  • race() 同样是将多个 Promise 实例,包装成一个新的 Promise 实例
  • allSettled()
  • resolve()
  • reject()
  • try()

2、Var、 let 、const 区别?(常问、必记)

varletconst三者区别可以围绕下面五点展开:

  • 变量提升
    var声明的变量存在变量提升,即变量可以在声明之前调用,值为undefined
    letconst不存在变量提升,即它们所声明的变量一定要在声明后使用,否则报错
  • 暂时性死区
    var不存在暂时性死区
    letconst存在暂时性死区,只有等到声明变量的那一行代码出现,才可以获取和使用该变量
  • 块级作用域
    var不存在块级作用域
    letconst存在块级作用域
  • 重复声明
    var允许重复声明变量
    letconst在同一作用域不允许重复声明变量
  • 修改声明的变量
    varlet可以
    const声明一个只读的常量。一旦声明,常量的值就不能改变
  • 使用
    能用const的情况尽量使用const,其他情况下大多数使用let,避免使用var

3、== 和 ===区别

相等操作符(==)会做类型转换,再进行值的比较,全等运算符(===)不会做类型转换

let result1 = ("55" === 55); // false,不相等,因为数据类型不同
let result2 = (55 === 55); // true,相等,因为数据类型相同值也相同

null 和 undefined 比较,相等操作符(==)为true,全等为false

let result1 = (null == undefined ); // true
let result2 = (null  === undefined); // false

4、数组常用方法

下面前三种是对原数组产生影响的增添方法,第四种则不会对原数组产生影响

  • push() 接收任意数量的参数,并将它们添加到数组末尾,返回数组的最新长度
  • unshift() 开头添加
  • concat() 首先会创建一个当前数组的副本,然后再把它的参数添加到副本末尾,最后返回这个新构建的数组,不会影响原始数组

下面三种都会影响原数组,最后一项不影响原数组:

  • pop() 删除数组的最后一项,同时减少数组的length 值,返回被删除的项
  • shift() 删除数组的第一项,同时减少数组的length 值,返回被删除的项
  • splice() 传入两个参数,分别是开始位置,删除元素的数量,返回包含删除元素的数组
  • slice() 创建一个包含原有数组中一个或多个元素的新数组,不会影响原始数组

即修改原来数组的内容,常用splice

传入三个参数,分别是开始位置,要删除元素的数量,要插入的任意多个元素,返回删除元素的数组,对原数组产生影响

即查找元素,返回元素坐标或者元素值

  • indexOf() 返回要查找的元素在数组中的位置,如果没找到则返回 -1
  • includes() 返回要查找的元素在数组中的位置,找到返回true,否则false
  • find() 返回第一个匹配的元素

排序方法

数组有两个方法可以用来对元素重新排序:

  • reverse() 将数组元素方向反转

下面这个被问过,所以重点展开

  • sort(首元素地址(必填), 尾元素地址的下一个地址(必填), 比较函数(非必填));

如果直接sort(数组名),则从小到大排序(即升序),以下为倒叙

var arr4 = [30,10,111,35,1899,50,45];
arr4.sort(function(a,b){
	return b - a;
})
console.log(arr4);//输出 [1899, 111, 50, 45, 35, 30, 10]

转换方法

常见的转换方法有:

join()

join() 方法接收一个参数,即字符串分隔符,返回包含所有项的字符串

迭代方法

常用来迭代数组的方法(都不改变原数组)有如下:

  • some() 对数组每一项都运行传入的函数,如果有一项函数返回 true ,则这个方法返回 true
  • every() 对数组每一项都运行传入的函数,如果对每一项函数都返回 true ,则这个方法返回 true
  • forEach() 对数组每一项都运行传入的函数,没有返回值
  • filter() 对数组每一项都运行传入的函数,函数返回 true 的项会组成数组之后返回
  • map() 对数组每一项都运行传入的函数,返回由每次函数调用的结果构成的数组.

去重方法

1、利用ES6 Set去重(ES6中最常用)

function unique (arr) {
  return Array.from(new Set(arr))
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr))
 //[1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {}, {}]

 

2、利用for嵌套for,然后splice去重(ES5中最常用)

function unique(arr){            
        for(var i=0; i<arr.length; i++){
            for(var j=i+1; j<arr.length; j++){
                if(arr[i]==arr[j]){         //第一个等同于第二个,splice方法删除第二个
                    arr.splice(j,1);
                    j--;
                }
            }
        }
return arr;
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
    console.log(unique(arr))
    //[1, "true", 15, false, undefined, NaN, NaN, "NaN", "a", {…}, {…}]     //NaN和{}没有去重,两个null直接消失了

 

3、利用indexOf去重

function unique(arr) {
    if (!Array.isArray(arr)) {
        console.log('type error!')
        return
    }
    var array = [];
    for (var i = 0; i < arr.length; i++) {
        if (array .indexOf(arr[i]) === -1) {
            array .push(arr[i])
        }
    }
    return array;
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr))
   // [1, "true", true, 15, false, undefined, null, NaN, NaN, "NaN", 0, "a", {…}, {…}]  //NaN、{}没有去重

 

4、利用includes

function unique(arr) {
    if (!Array.isArray(arr)) {
        console.log('type error!')
        return
    }
    var array =[];
    for(var i = 0; i < arr.length; i++) {
            if( !array.includes( arr[i]) ) {//includes 检测数组是否有某个值
                    array.push(arr[i]);
              }
    }
    return array
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
    console.log(unique(arr))
    //[1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {…}, {…}]     //{}没有去重

 

5、bind、call、apply 区别

  • 1.call和apply会调用函数,且会改变函数内部的this指向
    2.call和apply传递的参数不一样,call传递参数aru1,aru2.形式 而apply必须是数组形式[arg]
    3.bind 不会调用函数,可以改变函数内部指向
  • 应用场景:
    1.call经常做继承
    2.apply经常和数组有关系,比如借助于数学对象实现数组的max、min
    3.bind不调用函数,但改变this指向,比如改变定时器内部的this指向
  • apply:调用一个对象的一个方法,用另一个对象替换当前对象。例如:B.apply(A, arguments);即 A 对象应用 B 对象的方法。 call:调用一个对象的一个方法,用另一个对象替换当前对象。例如:B.call(A, args1,args2); 即 A 对象调用 B 对象的方法。 bind 除了返回是函数以外,它的参数和 call 一样。

6、本地存储的方式有哪些?区别及应用场景?

javaScript本地缓存的方法我们主要讲述以下四种:

  • cookie
  • sessionStorage
  • localStorage
  • indexedDB

区别

关于cookiesessionStoragelocalStorage三者的区别主要如下:

  • 存储大小:cookie数据大小不能超过4ksessionStoragelocalStorage虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大
  • 有效时间:localStorage存储持久数据,浏览器关闭后数据不丢失除非主动删除数据; sessionStorage数据在当前浏览器窗口关闭后自动删除;cookie设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭
  • 数据与服务器之间的交互方式,cookie的数据会自动的传递到服务器,服务器端也可以写cookie到客户端; sessionStoragelocalStorage不会自动把数据发给服务器,仅在本地保存

应用场景

在了解了上述的前端的缓存方式后,我们可以看看针对不对场景的使用选择:

  • 标记用户与跟踪用户行为的情况,推荐使用cookie
  • 适合长期保存在本地的数据(令牌),推荐使用localStorage
  • 敏感账号一次性登录,推荐使用sessionStorage
  • 存储大量数据的情况、在线文档(富文本编辑器)保存编辑历史的情况,推荐使用indexedDB

7、说说你对闭包的理解?闭包使用场景

闭包就是函数中包含另一个函数,可以让你在函数外部读取到内部的变量(就是在函数内部再定义一个函数),让这些变量的值始终保持在内存中,可以达到延长变量生命周期的效果,过多使用会导致内存泄漏的问题

(在创建私有变量和想延长变量的生命周期时会用到闭包)

8、深拷贝浅拷贝的区别?

浅拷贝,指的是创建新的数据,这个数据有着原始数据属性值的一份精确拷贝

如果属性是基本类型,拷贝的就是基本类型的值。如果属性是引用类型,拷贝的就是内存地址

JavaScript中,存在浅拷贝的现象有:

  • Object.assign
  • Array.prototype.slice()
  • Array.prototype.concat()
  • 使用拓展运算符实现的复制

深拷贝开辟一个新的栈,两个对象属完成相同,但是对应两个不同的地址,修改一个对象的属性,不会改变另一个对象的属性

常见的深拷贝方式有:

  • _.cloneDeep()
  • jQuery.extend()
  • JSON.stringify()
  • 手写循环递归

9、JavaScript中的数据类型?

string、number、Boolean、undefined、null、object

10、什么是防抖和节流?

定义

  • 防抖: n 秒后在执行该事件,若在 n 秒内被重复触发,则重新计时
  • 节流: n 秒内只运行一次,若在 n 秒内重复触发,只有一次生效

电梯第一个人进来后,等待15秒。如果过程中又有人进来,15秒等待重新计时,直到15秒后开始运送,这是防抖

电梯第一个人进来后,15秒后准时运送一次,这是节流

 

11、如何解决数字精度丢失的问题?

理论上用有限的空间来存储无限的小数是不可能保证精确的,但我们可以处理一下得到我们期望的结果

当你拿到 1.4000000000000001 这样的数据要展示时,建议使用 toPrecision 凑整并 parseFloat 转成数字后再显示,如下:

parseFloat(1.4000000000000001.toPrecision(12)) === 1.4  // True

封装成方法就是:

function strip(num, precision = 12) {
  return +parseFloat(num.toPrecision(precision));
}

最后还可以使用第三方库,如Math.js、BigDecimal.js

12、 JavaScript 中内存泄漏的几种情况?

使用闭包

13、原型,原型链 ? 有什么特点?

JavaScript 常被描述为一种基于原型的语言——每个对象拥有一个原型对象

当试图访问一个对象的属性时,它不仅仅在该对象上搜寻,还会搜寻该对象的原型,以及该对象的原型的原型,依次层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾

原型对象也可能拥有原型,并从中继承方法和属性,一层一层、以此类推。这种关系常被称为原型链 (prototype chain),它解释了为何一个对象会拥有定义在其他对象中的属性和方法

14、如何实现上拉加载,下拉刷新?

开源社区有很多优秀的解决方案,如iscrollbetter-scrollpulltorefresh.js库等等

15、说说你对作用域链的理解

1、作用域就是变量与函数的可访问范围

2、一般情况下,变量取值到创建这个变量的函数的作用域中取值。 但是如果在当前作用域中没有查到值,就会向上级作用域去查,直到查到全局作用域,这么一个查找过程形成的链条就叫做作用域链

16、typeof 与 instanceof 区别

typeofinstanceof都是判断数据类型的方法,区别如下:

  • typeof会返回一个变量的基本类型,instanceof返回的是一个布尔值
  • instanceof 可以准确地判断复杂引用数据类型,但是不能正确判断基础数据类型
  • typeof 也存在弊端,它虽然可以判断基础数据类型(null 除外),但是引用数据类型中,除了function 类型以外,其他的也无法判断

17、js基本数据类型

string、number、null、defined、boolean、object、symbol、bigint

18、ajax、axios、jsonp的理解

1、jsonp是一种可以解决跨域问题的方式,就是通过动态创建script标签用src引入外部文件实现跨域,script加载实际上就是一个get请求,并不能实现post请求。(其他实现跨域的方法有:iframe,window.name,postMessage,CORS...)

2、ajax是一种技术,ajax技术包含了get和post请求的,但是它仅仅是一种获取数据的技术,不能直接实现跨域,只有后台服务器配置好Access-Control-Allow-Origin,才可以实现请求的跨域。

4、axios是通过promise实现对ajax技术的一种封装,axios是ajax,ajax不止axios。

总结:

juery的$.ajax实现get请求能跨域是因为jsonp或者因为原生ajax和服务器的配合,post请求能跨域就只能是因为原生ajax和服务器的配合。

19、ajax的请求过程

// ajax 提交 post 请求的数据
// 1. 创建核心对象
var xhr = new XMLHttpRequest();
// 2. 准备建立连接
xhr.open("POST", "register.php", true);
// 3. 发送请求
// 如果要POST提交数据,则需要设置请求头
// 有的面试官会问为什么要设置请求头? 知道请求正文是以什么格式
// Content-Type: application/x-www-form-urlencoded,请求正文是类似 get 请求 url 的请求参数
// Content-Type: application/json,请求正文是一个 json 格式的字符串
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
// 发送数据
xhr.send(querystring);
// 4. 处理响应
xhr.onreadystatechange = function () {
     if (xhr.readyState === 4) { // 请求处理完毕,响应就绪
          if (xhr.status === 200) { // 请求成功
               var data = xhr.responseText;
               console.log(data);
          }
     }
}

 

20、ajax请求的时候get 和post方式的区别

1、get请求不安全,post安全 ;

2、get请求数据有大小限制,post无限制 ;

3、get请求参数会在url中显示,容易被他人窃取,post在请求体中,不会被窃取;

4、post需要设置请求头。

21、什么是事件委托以及优缺点

js事件委托就是利用冒泡的原理,把本应该添加到某个元素上的事件委托给他的父级,从而减少DOM交互达到网页优化。

优点:

1.可以大量节省内存占用,减少事件注册。比如ul上代理所有li的click事件就很不错。 2.可以实现当新增子对象时,无需再对其进行事件绑定,对于动态内容部分尤为合适

缺点:

事件代理的常用应用应该仅限于上述需求,如果把所有事件都用事件代理,可能会出现事件误判。即本不该被触发的事件被绑定上了事件。

 

---Vue部分---

1、为什么使用虚拟DOM(常问)

  • 创建真实DOM的代价高:真实的 DOM 节点 node 实现的属性很多,而 vnode 仅仅实现一些必要的属性,相比起来,创建一个 vnode 的成本比较低。
  • 触发多次浏览器重绘及回流:使用 vnode ,相当于加了一个缓冲,让一次数据变动所带来的所有 node 变化,先在 vnode 中进行修改,然后 diff 之后对所有产生差异的节点集中一次对 DOM tree 进行修改,以减少浏览器的重绘及回流。
  • 虚拟dom由于本质是一个js对象,因此天生具备跨平台的能力,可以实现在不同平台的准确显示。
  • Virtual DOM 在性能上的收益并不是最主要的,更重要的是它使得 Vue 具备了现代框架应有的高级特性。

2、Vue组件通信

 

父组件向子组件传值

  • 父组件发送的形式是以属性的形式绑定值到子组件身上。
  • 然后子组件用属性props接收
  • 在props中使用驼峰形式,模板中需要使用短横线的形式字符串形式的模板中没有这个限制

子组件向父组件传值

  • 子组件用$emit()触发事件
  • $emit() 第一个参数为 自定义的事件名称 第二个参数为需要传递的数据 $(event)来接收
  • 父组件用v-on 缩写为@ 监听子组件的事件

兄弟之间的传递

  • 兄弟之间传递数据需要借助于事件中心,通过事件中心传递数据
    • 提供事件中心 var hub = new Vue()

 

  • 传递数据方,通过一个事件触发hub.$emit(方法名,传递的数据)
  • 接收数据方,通过mounted(){} 钩子中 触发hub.$on()方法名
  • 销毁事件 通过hub.$off()方法名销毁之后无法进行传递数据

 

3、Vue中key是用来做什么的?为什么不推介使用index作为key?

1、key的作用主要是为了高效的更新虚拟DOM(使用key,它会基于key的变化重新排列元素顺序,并且会移除key不存在的元素)

2、当以数组的下标index作为index值时,其中一个元素(如增删改查)发生了变化就有可能导致所有元素的key值发生变化

4、生命周期:

  从Vue实例创建、运行、到销毁期间,伴随着的各种事件,这些事件统称为生命周期

生命周期函数分类:

  • 创建期间的生命周期函数:
    • beforeCreate:实例刚在内存中被创建出来,此时还没有初始化好data和methods属性
    • created:实例已经在内存中创建出来,此时的data和methods以及创建完成,但是还没有开始编译模板
    • beforeMount:此时已经完成了模板的编译,但是还没有挂载到页面上
    • mounted:已经将编译好的模板,挂载到了页面指定的容器中显示

 

  • 运行期间的生命周期函数:
    • beforeUpdate:状态更新之前执行此函数,此时data中的状态值是最新的,但是界面上显示的数据还是旧的,因为此时还没有开始重新渲染DOM节点
    • updated:实例更新完毕之后调用此函数,此时data中的状态值和界面上显示的数据,都已经完成了更新,界面已经被重新渲染好了

 

  • 销毁期间的生命周期函数:
  • 注意 !!!vue3,则是beforeunmount和unmount
    • beforeDestory:实例销毁之前调用,在这一步,实例仍然完全可用
    • destroyed:Vue实例销毁之后调用。调用后,Vue实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁

 

 

5、v-show和v-if的区别

v-show原理是修改元素的css属性display:none来决定是显示还是隐藏

v-if则是通过操作DOM来进行切换显示

6、双向数据绑定

实现mvvm的双向绑定,是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。

7、Vue导航守卫的钩子函数有哪些?

全局守卫

  • router.beforeEach:全局前置守卫,进入路由之前
  • router.beforeResolve:全局解析守卫,在beforeRouteEnter调用之后调用
  • router.afterEach:全局后置钩子,进入路由之后

路由组件内的守卫

  • beforeRouteEnter():进入路由前
  • beforeRouteUpdate():路由复用同一个组件时
  • beforeRouteLeave():离开当前路由时

8、vue编程式的导航跳转传参的方式有哪些?

// 命名的路由
router.push({ name: 'user', params: { userId: '123' }})
// 带查询参数,变成 /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})

 

9、vuex是什么?怎么使用?哪种功能场景使用它?

在main.js引入store,注入。新建了一个store目录,然后….. export 。 场景:单页应用中,组件之间的共享状态和方法 state Vuex 使用单一状态树,即每个应用将仅仅包含一个store 实例,但单一状态树和模块化并不冲突。存放的数据状态,不可以直接修改里面的数据。 mutations mutations定义的方法动态修改Vuex 的 store 中的状态或数据。 getters 类似vue的计算属性,主要用来过滤一些数据。 action actions可以理解为通过将mutations里面处里数据的方法变成可异步的处理数据的方法,简单的说就是异步操作数据。view 层通过 store.dispath 来分发 action。 modules 项目特别复杂的时候,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理。

10、mvc和mvvc的区别

MVC

 

MVC包括view视图层、controller控制层、model数据层。各部分之间的通信都是单向的。

View 传送指令到 Controller Controller 完成业务逻辑后,要求 Model 改变状态 Model 将新的数据发送到 View,用户得到反馈

MVVM

 

MVVM包括view视图层、model数据层、viewmodel层。各部分通信都是双向的。

采用双向数据绑定,View的变动,自动反映在 ViewModel,反之亦然。 mvvm代表框架:Angularjs、React、Vue mvvm主要解决了mvc中大量 dom操作使得页面渲染性能降低,加载速度变慢,影响用户体验

 

11、说出至少vue 3个常用事件修饰符?

.stop 阻止点击事件冒泡

.prevent 阻止默认事件

.once 只执行一次

.self 只在元素本身触发

12、vuex有哪几种属性

有五种,分别是State , Getter , Mutation , Action , Module (就是mapAction)

  1. state:vuex的基本数据,用来存储变量
  2. geeter:从基本数据(state)派生的数据,相当于state的计算属性
  3. mutation:提交更新数据的方法,必须是同步的(如果需要异步使用action)。每个mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数,提交载荷作为第二个参数。
  4. action:和mutation的功能大致相同,不同之处在于 ==》1. Action 提交的是 mutation,而不是直接变更状态。 2. Action 可以包含任意异步操作。
  5. modules:模块化vuex,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理。

HTTP

1、说一下http和https

http:超文本传输协议,是一个客户端和服务器端请求和应答的标准(TCP)

https:是以安全为目标的HTTP通道,即HPPT下加入SSL层,比http更安全

区别:

http传输的数据都是未加密的(明文),https协议是由https和SSL协议构建的可进行加密传输和身份认证的网络协议,需要ca证书,费用较高

2、tcp三次握手,一句话概括

客户端和服务端都需要直到各自可收发,因此需要三次握手

3、HTTP状态码

1xx Informational(信息性状态码) 接受的请求正在处理

2xx Success(成功状态码) 请求正常处理完毕

(1)、200 OK:表示从客户端发送给服务器的请求被正常处理并返回;

(2)、204 No Content:表示客户端发送给客户端的请求得到了成功处理,但在返回的响应报文中不含实体的主体部分(没有资源可以返回);

(3)、206 Patial Content:表示客户端进行了范围请求,并且服务器成功执行了这部分的GET请求,响应报文中包含由Content-Range指定范围的实体内容。

3xx Redirection(重定向) 需要进行附加操作以完成请求

(1)、301 Moved Permanently:永久性重定向,表示请求的资源被分配了新的URL,之后应使用更改的URL;

(2)、302 Found:临时性重定向,表示请求的资源被分配了新的URL,希望本次访问使用新的URL;

(3)、301与302的区别:前者是永久移动,后者是临时移动(之后可能还会更改URL)

(4)、303 See Other:表示请求的资源被分配了新的URL,应使用GET方法定向获取请求的资源;

(5)、302与303的区别:后者明确表示客户端应当采用GET方式获取资源

(6)、304 Not Modified:表示客户端发送附带条件(是指采用GET方法的请求报文中包含if-Match、If-Modified-Since、If-None-Match、If-Range、If-Unmodified-Since中任一首部)的请求时,服务器端允许访问资源,但是请求为满足条件的情况下返回改状态码;

(7)、307 Temporary Redirect:临时重定向,与303有着相同的含义,307会遵照浏览器标准不会从POST变成GET;(不同浏览器可能会出现不同的情况);

4xx Client error(客户端错误) 客户端请求出错,服务器无法处理请求

400 Bad Request:表示请求报文中存在语法错误;

401 Unauthorized:未经许可,需要通过HTTP认证;

403 Forbidden:服务器拒绝该次访问(访问权限出现问题)

404 Not Found:表示服务器上无法找到请求的资源,除此之外,也可以在服务器拒绝请求但不想给拒绝原因时使用;

5xx Server Error(服务器错误) 服务器处理请求出错

500 Inter Server Error:表示服务器在执行请求时发生了错误,也有可能是web应用存在的bug或某些临时的错误时;

503 Server Unavailable:表示服务器暂时处于超负载或正在进行停机维护,无法处理请求;

问你项目描述:

1.你这个项目的整体描述,需求,功能;

2.你这个项目所用到的技术栈,以及选择该技术栈的原因;

3.你这个项目中所遇到的问题,以及解决方法。

问你前端优化:

1、降低请求量:合并资源,减少HTTP请求数,minify/gzip压缩

2、加快请求速度:预解析DNS,减少域名数,并行加载

3、缓存:HTTP协议缓存请求,离线缓存manifest,离线数据缓存localStorage

4、渲染:JS/CSS优化,加载顺序,服务端渲染

 

原链接:https://zhuanlan.zhihu.com/p/422730888

posted @ 2022-08-27 11:11  偷熊计划  阅读(516)  评论(0编辑  收藏  举报