面试题--新增

h5新特性

(1)新的语义标签和属性
(2)表单新特性
(3)视频和音频
(4)Canvas绘图
(5)SVG绘图
(6)地理定位
(7)拖放API

CSS3新增的属性

border-radius

box-shadow

border-image

background-size

text-shadow

transform

box-sizing

垂直居中的方式

行高=高

Margin auto 0

绝对定位 top-50%,自身宽度的-50%

flex布局 align—center

水平居中的方式

绝对定位

flex布局 juest—center

margin 0 auto

text-align center

让一个盒子居中的办法

display:flex

margin : auto

margin 和padding

margin 外边距 padding内边距 不同点作用对象不同,margin 是盒子外部对象,padding是盒子内部对象

百分比%和vh有什么不同

%会继承父盒子的高和宽,vh没有继承

垂直居中DIV
<div class="father">
    <div class="son">我是垂直居中的div</div>
</div>

1.绝对定位(盒子宽高已知)

.father {
        position: relative;
        width: 500px;
        height: 500px;
        background-color: red;
    }
    
    .son {
        position: absolute;
        left: 50%;
        top: 50%;
        margin-left: -150px;(-盒子一半宽度)
        margin-top: -150px;(-盒子一半高度) 
        width: 300px;
        height:300px;
        background-color: blue;
    }

2.绝对定位(宽高已知)

.father {
        position: relative;
        width: 500px;
        height: 500px;
        background-color: red;
    }
    
    .son{
        position:absolute;
        margin:auto;
        top:0; left:0; bottom:0;right:0;
        width: 300px;
        height:300px;
        background-color: blue;
    }

3.定位 (宽高未知)

    .son {
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        background-color: blue;
    }

4.flex布局(父元素设置)

    .father {
        display: flex;
        align-items: center;
        justify-content: center;
        width: 500px;
        height: 500px;
        background-color: red;
    }
两栏布局左边固定右边自适应
    <div class="father">
        <div class="left"></div>
        <div class="right"></div>
    </div>

1.float布局

        .left {
            width: 200px;
            height: 200px;
            float: left;
            background-color: blue;
        }
        .right {
            margin-left: 200px;
            height: 200px;
            background-color: red;
        }

2.绝对定位

        .father {
            position: relative;
            height: 200px;
        }
        
        .left {
            position:absolute;
            width: 200px;
            height: 100%;
            float: left;
            background-color: blue;
        }

        .right {
            position:absolute;
            height: 100%;
            left:200px;
            right: 0;
            background-color: red;
        }

3.flex布局

        .father {
            height: 300px;
            width: 100%;
            display: flex;
        }

        .left {
            width: 300px;
            height: 100%;
            background-color: blue;
        }

        .right {
            flex: 1;
            height: 100%;
            background-color: red;
        }
三栏布局左右固定中自适应
    <div class="father">
        <div class="left"></div>
        <div class="right"></div>
        <div class="main"> </div>
    </div>

1.float布局

    .father{
        height: 50px;
         div{
            height: 100%;
        }
    }

    .left {
        width: 200px;
        float: left;
        background-color: red
    }

    .main {
        margin-left: 200px;
        margin-right: 200px;
        background-color: blue
    }

    .right {
        float: right;
        width: 200px;
        background-color: yellow
    }

2.绝对定位

    .father{
        position: relative;
        height: 50px;
          div{
            position: absolute;
            height: 100%;
        }
    }

    .left {
        left: 0;
        width: 200px;
        background-color: red
    }

    .main {
        left: 200px;
        right: 200px;
        background-color: blue
    }

    .right {
        right: 0;
        width: 200px;
        background-color: yellow
    }

3.flex布局

    .father {
        display: flex;
        height: 50px;
         div{
            height: 100%;
        }
    }

    .left {
        width: 200px;
        background-color: red
    }

    .main {
        flex: 1;
        background-color: blue
    }

    .right {
        width: 200px;
        background-color: yellow
    }
介绍一下盒模型

1.盒模型由内容(content)、内边距(padding)、边框(border)、外边距(margin)组成

2.盒模型分为IE盒模型和W3C标准盒模型。

3.W3C标准盒模型又叫content-box,元素宽度/高度由border+padding+content组成。

4.IE盒模型又叫border-box,元素宽度/高度由content组成。

阐述清除浮动的几种方式(常见问题)

1.父级div定义 height

2.父级div定义 overflow:hidden

  1. 结尾处加空div标签 clear:both

display none visibility hidden区别?

display:none是彻底消失,不在文档流中占位,浏览器也不会解析该元素

visibility:hidden是视觉上消失了,可以理解为透明度为0的效果,在文档流中占位,浏览器会解析该元素;

重绘与重排

重绘(repaint):当元素的外观属性发生变化,即元素的颜色,背景色发生改变但没有影响到dom树的位置改变的时候,会触发重绘;

**重排(reflow):**当页面内的元素尺寸发生了变化,导致部分或者全部DOM树,渲染树需要重新更新,会触发重排, 重排又称为回流;

如何产生:一般情况下,页面的重排必定会导致重绘,但重绘不一定会导致重排,写echarts容易引起重排
如何避免:避免频繁使用 style,而是采用修改class的方式。将动画效果应用到position属性为absolute或fixed的元素上。

使用class类名来控制样式的改变;对于复杂的动画效果可以使其脱离文档流;免循环操作DOM/避免循环读取offsetLeft等属性

也可以先为元素设置display: none,操作结束后再把它显示出来。因为在display属性为none的元素上进行的DOM操作不会引发回流和重绘
使用createDocumentFragment进行批量的 DOM 操作。
对于 resize、scroll 等进行防抖/节流处理。

bootstrap响应式实现的原理**

百分比布局+媒体查询

基本数据类型和引用数据类型

基本数据类型直接存储在栈内存中,占据空间小,大小固定,属于被频繁使用的数据

引用数据类型:同时存储在栈内存与堆内存中,占据空间大,大小不固定。

引用数据:类型将指针存在栈中,将值存在堆中。 当我们把对象值赋值给另外一个变量时,复制的是对象的指针,指向同一块内存地址

引用类型存储把值存储在堆内存中,堆内存是从下往上存储。生成唯一内存地址。然后在栈内存中把地址赋值给变量。栈内存是从上往下存储的

堆和栈有什么区别存储机制

是一种连续储存的数据结构,具有先进后出的性质。

通常的操作有入栈(压栈),出栈和栈顶元素。想要读取栈中的某个元素,就是将其之间的所有元素出栈才能完成。

是一种非连续的树形储存数据结构,每个节点有一个值,整棵树是经过排序的。特点是根结点的值最小(或最大),且根结点的两个子树也是一个堆。常用来实现优先队列,存取随意。

BFC

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

触发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
Javascript中的定时器有哪些?他们的区别及用法是什么?

setTimeout 只执行一次
setInterval 会一直重复执行

null 和 undefined 的区别

null 是表示‘无’的对象,转为数值时为0,比如:作为函数的参数,表示该函数的参数不是对象;作为对象原型链的终点,null 转化为值时为0

undefined 是一个表示‘无’的原始值,转为数值时为NaN,

1变量被声明了,但没有赋值时,就等于undefined。
2调用函数时,应该提供的参数没有提供,该参数等于undefined。
3对象没有赋值的属性,该属性的值为undefined。
4函数没有返回值时,默认返回undefined。

null 转化为值时为NaN

深拷贝和浅拷贝

深拷贝是拷贝一个对象活数组,他们之间不会相互影响,平时经常用的 JSON.parse(JSON.stringify()).,但多维数组活着对象会相互影响

浅拷贝就是拷贝一个对象活着数组,他们之间会相互影响

判断数据类型的方法

typeof 检测数据: 缺点:无法判断null和object 返回值:数据类型检测数据

instanceof: 缺点:无法判断字面量创建的基本数据类型 返回值:boolean 原理:实际上就是查找目标对象的原型链

检测数据.constructor.name: 返回值:数据类型Object.prototype.toString.call(检测数据): 返回值:“[object Number]”

垃圾回收机制和内存泄漏

什么是垃圾回收机制:在JavaScript中,一般来说没有被引用的对象就是垃圾,就是要被清除;

内存泄露:是指当一块内存不再被应用程序使用的时候,由于某种原因,这块内存没有返还给操作系统或者内存池的现象。
闭包常驻内存

原型,原型链、构造函数

原型:js中万物皆对象,每一个对象都有自己的属性和方法,因为要解决属性或方法的共享问题,所以就出现了原型。

构造函数:原型对象的constructor 指向所创建它的构造函数。

实例对象:构造函数通过new方法创建一个实例对象;实例对象上的_____proto_默认指向它的原型对象。

原型对象:每一个函数或者对象在被创建时,都会添加一个prototype属性,默认指向它的原型对象。

原型链:js在查找属性或方法的过程中,如果在自己的属性中找不到就会沿着_____proto_____去找原型对象,

如果原型对象中还找不到,就继续沿着原型对象的_____proto_____中查找,这种通过_____proto_____查找的过程就叫做原型链

原型链其实就是继承链,首先在这个对象的自身查找,如果没有该属性,就在其原型链上一层一层向上查找,如果查到原型链的顶端也没有该属性,那么就返回null。

JavaScript六种继承

1.原型链:原型链继承基本思想就是让一个原型对象指向另一个类型的实例

2.借用构造函数 :为了解决原型中包含引用类型值所带来的问题 这种方法的思想就是在子类构造函数的内部调用父类构造函数,可以借助apply()和call()方法来改变对象的执行上下文

3.组合继承(原型链+构造函数):使用原型链实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承

4.原型式继承:借助原型可以基于已有的对象创建新对象,同时还不必因此创建自定义类型

5.寄生式继承:寄生式继承的思路与寄生构造函数和工厂模式类似,即创建一个仅用于封装继承过程的函数

6.寄生组合式继承:组合模式(原型链+构造函数)中,继承的时候需要调用两次父类构造函数 父类

cookies,sessionStorage 和 localStorage

cookie:生命周期为人为设置,在过期时间之前都是有效的。每次http请求都会携带cookie。大小约为4kb
sessionStorage:生命周期为仅在当前浏览器窗口关闭之前有效,关闭页面或者浏览器会被清除。不参与和服务器的通信。大小约5M或者更大
localStorage:永久有效,窗口或者浏览器关闭也会一直保存,除非手动永久清除。不参与和服务器的通信。大小约5M或者更大
removeItem()/setItem()/clear()/getItem()

undefined 和 null 区别

null表示没有对象,即不应该有值,经常用作函数的参数,或作为原型链的重点

undefined表示缺少值,即应该有值,但是还没有赋予(变量提升时默认会赋值为undefined,函数参数未提供默认为undefined,函数的返回值默认为undefined)

事件委托/事件代理

事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。
是利用事件冒泡的特性,将本应该注册在子元素上的事件处理程序注册在了父组件身上,
这样点击子元素时,发现其没有相应事件就会到父元素上寻找做做出响应,这样做的优势有:
1、减少dom操作,提高性能
2、随时都可以添加子元素,子元素也有相应的事件处理程序

常见的HTTP状态码

200 (成功) 服务器已成功处理了请求。 通常,这表示服务器提供了请求的网页。

301 (永久移动) 请求的网页已永久移动到新位置。 服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置。

400 (错误请求) 服务器不理解请求的语法。

403 (禁止) 服务器拒绝请求。

500 (服务器内部错误) 服务器遇到错误,无法完成请求。

503 (服务不可用) 服务器目前无法使用(由于超载或停机维护)。 通常,这只是暂时状态。

常用的es6的功能?

1.let、const
let定义变量,可以被重新赋值;const定义常量,不能被重新赋值
2.解构赋值
按照一定的模式从数组或者对象中取值,对变量进行赋值的过程
3.模板字符串 ‘’
4.块级作用域
5.箭头函数

this指向?

1.普通函数胡它还会this指向window
2.构造函数this指向实例对象
3.调用方法this指向改方法所属的对象
4.定时器this指向window

改变this指向的方法?

1.call()
2.apply()
3.bind()

数组去重?
  1. IndexOf()
  2. 双重for循环
  3. es6的 […new Set()]
  4. filter()
  5. sort()

1.Set去重
var arr = [1,1,8,8,12,12,15,15,16,16];
function unique (arr) {
return Array.from(new Set(arr))
}

console.log(unique(arr)) //1,8,12,15,16

闭包的理解

理解:主要是为了设计私有的方法和变量。
优点:可以避免全局变量造成污染。
缺点:闭包会常驻内存,增加内存使用量,使用不当会造成内存泄漏。
特征:(1)函数嵌套函数。(2)在函数内部可以引用外部的参数和变量。(3)参数和变量不会以垃圾回收机制回收。

Promise
异步编程的一种解决方案,用来解决回调地狱

三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败) (Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。)

resolved函数作用:将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved)。
reject函数的作用:将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected)。

Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数。
then: Promise 实例添加状态改变时的回调函数。可以接受两个回调函数作为参数。第一个回调函数是Promise对象的状态变为resolved时调用,第二个回调函数是Promise对象的状态变为rejected时调用。

缺点:无法取消Promise,一旦新建它就会立即执行,无法中途取消。如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。

promise 的理解

1、promise是一个构造函数,通过new方法可以用来创建一个Promise对象
2、异步编程的一种解决方案,用来解决回调地狱
3、promise有三种状态,peddding reslove rejected,状态一旦改变,就无法再次改变状态,一个promise对象只能改变一次
4、promise.all()用于将多个 Promise 实例,包装成一个新的 Promise 实例
==> promise1和promise2都成功才会调用success1
5、Promise.race()方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例
==>promise1和promise2只要有一个成功就会调用success1

说一下宏任务和微任务?

JS是单线程,代码自上而下执行;
宏任务:当前调用栈中执行的代码成为宏任务(定时器)
微任务:当前宏任务执行完,在下一个宏任务开始之前需要执行的任务,可以理解为事件的回调(promise.then/proness.nextTick)

宏任务与微任务执行顺序:

script代码为第一层宏任务,如果有setTimeout,setInterval,则他们的回调函数会成为第二层的宏任务,
promise.then()和process.nextTick()是微任务,在执行完该一层的宏任务后执行,且process.nextTick()优先于promise.then();

数组一些常用的方法(es5+es6)

1.添加(push与unshift)
2.删除(pop与shift)
3.从数组中连续删除、插入数据:splice()
4.数组串联:join()
5.数组排序:sort()
6.数组颠倒:reverse()
7.数组抽取:slice()
8.数组合并:concat()
9.数组转为字符串:toString()
(ES5中数组常用方法)
1.forEach()
2.map(映射)
3.filtter(过滤)
4.every(所有)和some(存在)
5.reduce()和reduceRight()
6.indexOf()和lastIndexOf()

对象一些常用的方法

1、Object.keys( ) 对象不具有length属性,因此,你也可以通过Object.keys( )用来获取对象的长度

2、Object.freeze( ) 防止对象中的数据突变

3、Object.seal( ) 它可以防止向对象添加新属性,但是可以更改和更新现有属性

4、Object.values( )允许你将对象内的所有值作为数组获取

5、Object.entries( ) 它允许你同时获取对象的键和值,并返回一个多维数组,该多维数组包含每个键和值的其他数组。

6、Object.create( ) 用于从另一个现有对象的原型创建一个新对象。

作用域和作用域链

JavaScript有全局作用域和函数作用域、块作用域。
1、作用域最大的用处就是隔离变量,不同作用域下同名变量不会有冲突。
2、所有末定义直接赋值的变量自动声明为拥有全局作用域
3、作用域是分层的,内层作用域可以访问外层作用域的变量,反之则不行。
作用域链:如果父级也没呢?再一层一层向上寻找,直到找到全局作用域还是没找到,就宣布放弃。
这种一层一层的关系,就是 作用域链 。
执行上下文在运行时确定,随时可能改变;作用域在定义时就确定,并且不会改变。

怎样添加、移除、移动、复制、创建和查找节点?

1)创建新节点

createDocumentFragment() //创建一个DOM片段
createElement() //创建一个具体的元素
createTextNode() //创建一个文本节点

2)添加、移除、替换、插入
appendChild() //添加
removeChild() //移除
replaceChild() //替换
insertBefore() //插入

3)查找
getElementsByTagName() //通过标签名称
getElementsByName() //通过元素的Name属性的值
getElementById() //通过元素Id,唯一性

页面渲染html的过程?

1.浏览器根据请求的URL交给DNS域名解析,找到真实IP;
2.浏览器根据 IP 地址向服务器发起 TCP 连接,与浏览器建立 TCP 三次握手
3、发送HTTP请求,接受HTTP响应
5.服务器处理请求并返回内容。
6、根据 HTTP 请求中的内容来决定如何获取相应的 HTML 文件,浏览器解析HTML代码,请求js,css等资源,最后进行页面渲染,呈现给用户

输入 url 后会发生什么?

1.DNS域名解析;
2.建立TCP连接;
3.发送HTTP请求;
4.服务器处理请求并返回响应结果;
5.关闭TCP连接;
6.浏览器解析HTML并布局渲染;

TCP三次握手和四次挥手
三次握手:(客户端和服务端都需要直到各自可收发,因此需要三次握手)

第一次:客户端请求建立链接
第二次:服务器端针对客户端的SYN的确认应答并建立链接
第三次:客户端针对服务器端的SYN的确认应答
完成三次握手,随后客户端与服务器端之间可以开始传输数据了

四次挥手:

第一次:客户端请求断开链接
第二次:服务器端针对客户端的FIN的确认应答
第三次:服务器端请求断开链接
第四次:客户端针对服务器端的FIN的确认应答
服务器收到客户端的确认后,就关闭链接,此刻客户端等待一段时间后没有收到回复,就已经证明服务器端已经关闭,这时候客户端也可以关闭链接了

HTTP与HTTPS

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

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

区别:

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

TCP与UDP的区别

TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接。
TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的
每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信
TCP首部开销20字节;UDP的首部开销小,只有8个字节。
TCP提供可靠的服务。UDP适用于一次只传少量数据、对可靠要求不高的环境。

GET和POST的区别

1、get请求是获取数据的,而post请求是提交数据的。
2、get请求能被缓存,post请求不能被缓存
3、get请求对数据长度的限制;当发送数据时,GET 方法向 URL 添加数据get请求的传送数据会拼接在url后面
4、GET在浏览器回退时是无害的,而POST会再次提交请求。
5、GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。
6、GET参数通过URL传递,POST放在Request body中。

堆(heap)和栈(stack)有什么区别存储机制

栈: 是一种连续储存的数据结构,具有先进后出后进先出的性质

通常的操作有入栈(压栈),出栈和栈顶元素。想要读取栈中的某个元素,就是将其之间的所有元素出栈才能完成

堆: 是一种非连续的树形储存数据结构,具有队列优先,先进先出

每个节点有一个值,整棵树是经过排序的。特点是根结点的值最小(或最大),且根结点的两个子树也是一个堆。常用来实现优先队列,存取随意。

如何解决跨域
什么是跨域?

浏览器从一个域名的网页去请求另一个域名的资源时,域名、端口、协议任一不同,都是跨域

常见的:

1、JSONP跨域 —原理就是利用了script标签,在标签外套了一层壳,利用标签特性达到跨域加载资源的效果

2、跨域资源共享(CORS)—跨站资源共享,它是跨域的官方解决方案,升级版的JSONP。原理是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功还是失败。请求和响应都不包含cookie信息。

3、nginx代理—代理跨域。反向代理跨域。

4、WebSocket协议跨域 ----不受同源策略影响。原理是因为它不使用HTTP协议,而使用一种自定义的协议,专门为快速传输小数据设计

对MVC和MVVM的理解

M:model(数据模型),V:view(视图),C:controller(逻辑处理),VM:(连接model和view)
MVC:单向通信。必须通过controller来承上启下。
MVVM:数据双向绑定,数据改变视图,视图改变数据。

深拷贝,浅拷贝

浅拷贝:创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是内存地址 ,所以如果其中一个对象改变了这个地址,就会影响到另一个对象。

深拷贝:将一个对象从内存中完整的拷贝一份出来,从堆内存中开辟一个新的区域存放新对象,且修改新对象不会影响原对象

防抖与节流

防抖:触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间
应用场景:
提交按钮、用户注册时候的手机号验证、邮箱验证、

节流:高频事件触发,但在n秒内只会执行一次,所以节流会稀释函数的执行频率
应用场景:
window对象的resize、scroll事件
拖拽时候的mousemove
射击游戏中的mousedown、keydown事件
文字输入、自动完成的keyup事件性能优化

性能优化
  1. 减少http请求次数
  2. 减少DNS查找
  3. 避免重定向
  4. 使用Ajax缓存
  5. 少用全局变量、减少DOM操作的使用
  6. 优化图片大小,通过CSS Sprites(精灵图)优化图片,
  7. 将css放在顶部,将js放在底部
webpack是怎么打包的,babel又是什么

Webpack:把所有依赖打包成一个 bundle.js文件,通过代码分割成单元片段并按需加载。Webpack是以公共JS的形式来书写脚本的,但对AMD/CMD的支持也很全面,方便旧项目进行代码迁移。
把项目当做一个整体,通过一个给定的主文件(如:index.js),Webpack将从这个文件开始找到项目的所有依赖文件,使用loaders处理它们,最后打包为一个(或多个)浏览器可识别的JavaScript文件。

babel 将es6、es7、es8等语法转换成浏览器可识别的es5或es3语法。

git 和 svn的区别

SVN是集中式版本控制系统,版本库是集中放在中央服务器的,首先要从中央服务器哪里得到最新的版本,干完活后,需要把自己做完的活推送到中央服务器。集中式版本控制系统是必须联网才能工作(如果在局域网还可以,带宽够大,速度够快,如果在互联网下,如果网速慢的话,就纳闷了)

Git是分布式版本控制系统,没有中央服务器的,每个人的电脑就是一个完整的版本库,这样,工作的时候就不需要联网了,因为版本都是在自己的电脑上。自己在电脑上改了文件A,其他人也在电脑上改了文件A,这时,只需把各自的修改推送给对方,就可以互相看到对方的修改了。

webSocket

webSocket:只要建立一次连接,就可以连续不断的得到服务器推送的消息,节省带宽和服务器端的压力。

WebSocket协议是基于TCP的一种新的网络协议。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

Vue的优点
  1. 轻量级框架:只关注视图层,是一个构建数据的视图集合,大小只有几十 kb ;
  2. 简单易学:国人开发,中文文档,不存在语言障碍 ,易于理解和学习;
  3. 双向数据绑定:保留了 angular 的特点,在数据操作方面更为简单;
  4. 组件化:保留了 react 的优点,实现了 html 的封装和重用,在构建单页面应用方面有着独特的优势;
  5. 视图,数据,结构分离:使数据的更改更为简单,不需要进行逻辑代码的修改,只需要操作数据就能完成相关操作;
  6. 虚拟DOM:dom 操作是非常耗费性能的, 不再使用原生的 dom 操作节点,极大解放 dom 操作,但具体操作的还是 dom 不过是换了另一种方式;
  7. 运行速度更快:相比较于 react 而言,同样是操作虚拟 dom ,就性能而言, vue 存在很大的优势。
Vue中双向数据绑定是如何实现的?

(答:通过数据劫持结合发布—订阅模式,通过Object.defineProperty()为各个属性定义get、set方法,在数据发生改变时给订阅者发布消息,触发相应的事件回调。)
getter: 是读取对象属性时调用的函数(实际上执行的是get方法)
setter: 是写入对象属性时调用的函数(实际上执行的是set方法)

vue 双向数据绑定是通过 数据劫持 结合 发布订阅模式的方式来实现的, 也就是说数据和视图同步,数据发生变化,视图跟着变化,视图变化,数据也随之发生改变;

核心:关于VUE双向数据绑定,其核心是 Object.defineProperty()方法

vue生命周期

概念:从创建、初始化数据、编译模板、挂载DOM、渲染-更新-渲染、卸载等一系列过程,称为为Vue 实例的生命周期。

beforeCreate:创建前。此时,组件实例刚刚创建,还未进行数据观测和事件配置,拿不到任何数据。

created:创建完成。vue 实例已经完成了数据观测,属性和方法的计算(比如props、methods、data、computed和watch此时已经拿得到),但尚未开始挂载。

beforeMount:挂载前。挂在开始之前被调用,相关的render函数首次被调用(虚拟DOM)。编译模板,把data里面的数据和模板生成html,完成了el和data 初始化,注意此时还没有挂在html到页面上。
mounted:挂载完成。也就是模板中的HTML渲染到HTML页面中,此时一般可以做一些ajax操作,mounted只会执行一次。
beforeUpdate:在数据更新之前被调用,发生在虚拟DOM重新渲染和打补丁之前,不会触发附加地重渲染过程。
updated:更新后。在由于数据更改导致地虚拟DOM重新渲染和打补丁之后调用,
beforeDestroy;销毁前。在实例销毁之前调用,实例仍然完全可用。(一般在这一步做一些重置的操作,比如清除掉组件中的定时器 和 监听的dom事件)
destroyed:销毁后。在实例销毁之后调用,调用后,vue实列指示的所有东西都会解绑,所有的事件监听器会被移除。
其他:
activated:在keep-alive组件激活时调用。
deactivated:在keep-alive组件停用时调用。

详述keep-alive组件

keep-alive是Vue的内置组件,能在组件切换过程中,将组件状态保留在内存中,防止重复渲染DOM,降低渲染成本。

包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们,它自身不会渲染一个 DOM 元素,也不会出现在父组件链中

keep-alive的生命周期-重要

1、activated:来缓存组件状态,页面第一次进入的时候,钩子触发的顺序是created>mounted>activated,之后再进入页面的时候,不会触发created,只会触发activated,也就是activated在这时代替了created。

2、deactivated :页面退出的时候会触发deactivated,当再次前进或者后退的时候只触发activated

vue中key的作用

为了更准确的DOM Diff算法。通过给相同层级的节点设置key属性,其中key是标识每个节点的唯一值,这就避免了实际项目中在DOM更新的时候"就地更新”而带来的意外bug。

$nextTick的理解

在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM

使用场景
在你更新完数据后,需要及时操作渲染好的 DOM时

Vue中常用的一些指令

1.v-model指令:用于表单输入,实现表单控件和数据的双向绑定。
2.v-on:简写为@,基础事件绑定
3.v-bind:简写为:,动态绑定一些元素的属性,类型可以是:字符串、对象或数组。
4.v-if指令:取值为true/false,控制元素是否需要被渲染
5.v-else指令:和v-if指令搭配使用,没有对应的值。当v-if的值false,v-else才会被渲染出来。
6.v-show指令:指令的取值为true/false,分别对应着显示/隐藏。
7.v-for指令:遍历data中存放的数组数据,实现列表的渲染。
8.v-once: 通过使用 v-once 指令,你也能执行一次性地插值,当数据改变时,插值处的内容不会更新

组件之间如何传值

1.父传子:props
父组件通过 props 向下传递数据给子组件。注:组件中的数据共有三种形式:data、props、computed

2.子传父:通过事件形式
子组件通过 $emit()给父组件发送消息,父组件通过v-on绑定事件接收数据。

3.vuex

vuex 是 vue 的状态管理器,存储的数据是响应式的。只需要把共享的值放到vuex中,其他需要的组件直接获取使用即可;

路由传值的区别

1.params只能用name来引入路由,query用path/name来引入
2.params类似于post,query更加类似于我们ajax中get传参,说的再简单一点,前者在浏览器地址栏中不显示参数,后者显示,所以params传值相对安全一些
3.取值用法类似分别是this. r o u t e . p a r a m s . n a m e 和 t h i s . route.params.name和this. route.params.namethis.route.query.name。
4.params传值一刷新就没了,query传值刷新还存在,

路由之间如何传参
  • 跳转时使用push方法拼接携带参数**

     this.$router.push({
              path: `/getlist/${id}`,
            })
    
    • 通过路由属性中的name来确定匹配的路由,通过params来传递参数。
this.$router.push({
          name: 'Getlist',
          params: {
            id: id
          }
        })

  • 使用path来匹配路由,然后通过query来传递参数**

    this.$router.push({
              path: '/getlist',
              query: {
                id: id
              }
            })
    

谈一谈VUEX

原理:Vuex是专门为vue.js应用程序设计的状态管理工具。
构成:

state:vuex的基本数据,用来存储变量。
mutations:提交更改数据,同步更新状态。
actions:提交mutations,可异步操作。
getters:是store的计算属性。
modules:模块,每个模块里面有四个属性。

简述Vuex工作流程

1、通过dispath来触发actions提交修改数据操作
2、再通过actions的commit来触发mutations来修改数据
3、mutations接收到commit的请求,就会自动通过mutate来修改state里的数据
4、最后由store触发每一个调用它的组件就更新视图了
vuex的作用:项目数据状态集中管理,复杂组件(兄弟组件)的数据通信问题

watch和computed的区别

computed一定有返回值,而watch不需要返回值
computed是依赖的数据发生改变时重新调用, watch是监听的响应式数据发生改变时重新调用

watch和methods的区别

methods是每次调用都会执行函数
watch不需要调用,并且只有监听数据发生改变时才会重新调用

route和router的区别
  • route 相当于当前正在跳转的路由对象。可以从里面获取name,path,params,query等
  • Router 相当于一个全局的路由器对象,里面含有很多属性和子对象,例如history对象。。。经常用的跳转链接就可以用this.$router.push,和router-link跳转一样。
vue-router路由跳转方式

1.声明式(标签跳转)

  <router-link :to="{name:'home'}"></router-link>
  <router-link :to="{path:'/home'}"></router-link>

2.编程式( js跳转)

this.$router.push('/home')
this.$router.push({name:'home'})
this.$router.push({path:'/home'})
v-show和v-if的区别

相同点:
v-show和v-if都能控制元素的显示和隐藏。
不同点:
1.实现本质方法不同:v-show本质就是通过设置css中的display设置为none;控制隐藏v-if是动态的向DOM树内添加或者删除DOM元素;
2.v-show都会编译,初始值为false,只是将display设为none,但它也编译了;v-if初始值为false,就不会编译了
总结:v-show只编译一次,后面其实就是控制css,而v-if不停的销毁和创建,如果要频繁切换某节点时,故v-show性能更好一点。

为什么避免v-if和v-for一起使用

当 v-if 与 v-for 一起使用时,v-for 具有比 v-if 更高的优先级;

Vue.set 改变数组和对象中的属性

在一个组件实例中,只有在data里初始化的数据才是响应的,Vue不能检测到对象属性的添加或删除,没有在data里声明的属性不是响应的,所以数据改变了但是不会在页面渲染;
解决办法:
使用 Vue.set(object, key, value) 方法将 响应属性添加到嵌套的对象上

vue中data为什么是函数而不是对象?

在Vue中组件是可以被复用的,而当data是一个函数的时候,每一个实例的data都是独立的,不会相互影响了。

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

全局守卫

beforeEach-前置钩子,进入之前
参数:to(去哪)、from(从哪来)、next(是否跳转由它决定)
使用场景:没登录去下单,跳到登录页
afterEach-后置钩子,进去之后
参数:to(去哪)、from(从哪来)
使用场景:改变浏览器title

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

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

加载慢的原因

  • 网络延时问题

  • 资源文件体积是否过大

  • 资源是否重复发送请求去加载了

  • 加载脚本的时候,渲染内容堵塞了

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

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

vue首屏加载优化

第一,路由懒加载。

第二,使用CDN引入第三方依赖。

1. 为什么使用CDN

使用CDN主要解决两个问题:

  • 打包时间太长、打包后代码体积太大,请求慢
  • 服务器网络不稳带宽不高,使用cdn可以回避服务器带宽问题

第三,按需加载第三方类库

第四,去掉编译文件中map文件

第五,将静态资源使用cdn加载

第六,开启 gzip压缩

第七,冗余代码

第八,浏览器缓存

基本原理:浏览器缓存分强缓存和协商缓存,他们是将网络资源存储在本地,等待下次请求该资源时,如果命中就不需要到服务器重新请求该资源,直接在本地读取该资源。

  • 强缓存:在web服务器返回的响应中添加Expires和Cache-Control Header
  • 协商缓存:通过【Last-Modified, If-Modified-Since】和【ETag, If-None-Match】两对Header分别管理

第九,图片压缩

前端的报错类型

1、xxx is not defined

xxx 没有定义

2、xxx is not a function

xxx 不是一个函数
xxx此时是undefined

3、Cannot read property ‘xxx’ of undefined

不能读取undefined的xxx属性

xxx前面的变量是undefined

4、Cannot set property ‘xxx’ of null

不能给null设置xxx属性

xxx前面的变量是null

请描述一下 cookies sessionStorage和localstorage区别

**相同点:**都存储在客户端

localStorage 存储持久数据,浏览器关闭后数据不丢失除非主动删除数据;

sessionStorage 数据在当前浏览器窗口关闭后自动删除。

cookie 设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭

cookie的数据会自动的传递到服务器,服务器端也可以写cookie到客户端

· sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。

Vue开发环境和服务器部署的跨域问题解决方案

开发环境中,由于域名ip端口的不同会遇到跨域的问题,此时我们需要配置代理服务,在根目录新增 vue.config.js 文件。

module.exports = {
    devServer: {
        proxy: {
            '/api': {
                target: 'http://107.10.128.59:8082/', //接口域名
                changeOrigin: true,             //是否跨域
                ws: true,                       //是否代理 websockets
                secure: true,                   //是否https接口
                pathRewrite: {                  //路径重置
                    '^/api': ''
                }
            }
        }
    }
}

浏览器的缓存机制也就是我们说的 HTTP 缓存机制

强缓存和协商缓存
是浏览器在本地磁盘对用户最近请求过的文档进行存储,当访问者再次访问同一页面时,浏览器就可以直接从本地磁盘加载文档。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值