vue知识点总结

# 1.ES6新增?

*1、变量的改变*

  *let:代码块内有效;不能重复声明;不存在变量提升*

  *const:只读变量,声明之后不允许改变。意味着,一旦声明必须初始化,否则会报错。;*

*2、模版字符串(``)*

*3、函数*

   **1、箭头函数 (sender) => { }

        箭头函数最直观的三个特点。

        不需要function关键字

        可以省略return关键字

        继承当前上下文的this关键字**

        *箭头函数限制:1.不能用箭头函数进行new 操作;2.不具有this,所以不能用作构造函数*

    **2、函数设置默认参数**

*4、数组新增方法*

   **1、forEach():数组的遍历方法,无返回值,不改变原数组**

   **2、map():map遍历数组,返回一个新数组,不改变原数组的值。**

   **3、filter():filter过滤掉数组中不满足条件的值,返回一个新数组,不改变原数组的值。**

   **4、reduce():reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。

**

   **5、some():遍历数组每一项,有一项返回true,则停止遍历,结果返回true。不改变原数组**

   **6、every()://遍历数组每一项,每一项返回true,则最终结果为true。当任何一项返回false时,停止遍历,返回false。不改变原数组

// 与some()方法互补**

   *5、import 和 export*

   *6、Promise:就是用同步的方式去写异步代码。 仅仅是同步            的方式 代码还是异步执行,Promise是一个构造函数,自己身上有all、reject、resolve这几个眼熟的方法,原型上有then、catch等同样很眼熟的方法 ----Promise.all()方法*

   *7.解构赋值:解构赋值,简单理解就是等号的左边和右边相等。*

   *8.对象新增的方法:*

   **Object.assign方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target**

   **Object.keys方法,返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键名**

   *9.set和map*

   **Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。**

   **Map 数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作**

     

#2.vue路由懒加载实现?

 *当打包构建应用时,JavaScript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。结合 Vue 的异步组件和 Webpack 的代码分割功能*

 *1、可以将异步组件定义为返回一个 Promise 的工厂函数 (该函数返回的 Promise 应该 resolve 组件本身):*

 *2、在 Webpack 2 中,我们可以使用动态 import语法来定义代码分块点,在路由配置中什么都不需要改变,只需要像往常一样使用*

 

 **require和import from 的区别**

 *import(编译时加载)只能用于静态输入,必须在文件开始的时候,在最上层就写好,而require(运行时加载)可以实现动态加载*

 

#3.vue生命周期

*创建阶段:*

 **1、beforeCreat:初始化了一个空的vue实例对象,对象身上只有一些默认的生命周期函数和默认事件,其他什么都没有**

 **注:该阶段data和methods中的数据都还没有初始化**

 **2:created:data和methods中的数据都已经初始化了,如果要操作data中的数据或者调用methods中的方法,最早只能在这个阶段**

 *挂载阶段:*

 **3、beforeMount:模板已经在内存中编译好了,尚未挂载到页面,此时页面还是旧的**

 **4、mounted:将内存中编译的模板挂载到页面,若要操作页面上的节点,最早在该阶段**

 *运行阶段:*

 **1、beforeUpdate:该阶段data中的数据是最新的,但尚未和页面保持同步,页面中显示的数据还是旧的**

 **2、updated:页面和data数据保持同步,页面为最新**

 *销毁阶段:清除定时器*

 **beforeDestroy:该阶段实例身上的data和methods、过滤器及指令都还可用**

 **destroyed:组件已经被完全销毁**

#4.webpack、请配置求数据封装

*出口、入口文件、loader、*

#5.判断数组方法

*对数组和对象使用typeof,得出的结果都是"object"*

*区分数组和对象的方法:*

   **使用instanceof进行判断,A instanceof B即对象A是不是构造函数B构造出来的,是数组即返回true, 不是即返回false**

   **利用Object.prototype.toString.call()方法将该变量转化为代表其类型的string**

   **Array.isArray(A)**

   **利用constructor属性进行判断**

   

   *数组去重*

    **ES6的Array.from()**

    **new Set:Set 的成员具有唯一性**

    **遍历数组,建立新数组,利用indexOf判断是否存在于新数组中,不存在则push到新数组,最后返回新数组(indexOf() 方法可返回某个指定的字符串值在字符串中首次出现的位置,如果要检索的字符串值没有出现,则该方法返回 -1。)**

    **遍历数组,利用object对象的key值保存数组值(key不重复),判断数组值是否已经保存在object中,未保存则push到新数组并用object[arrayItem]=true的方式记录保存.**

#6.浏览器兼容问题(BOM、DOM)

#7.VUEX使用场景

*购物车、权限登录、非父子组件传值*

#8.VUE和react对比

*相同的:*

**都使用 Virtual DOM**

**都提供了响应式 (Reactive) 和组件化 (Composable) 的视图组件。**

**都将注意力集中保持在核心库,而将其他功能如路由和全局状态管理交给相关的库**

*不同:*

   **1.优化:在 React 应用中,当某个组件的状态发生变化时,它会以该组件为根,重新渲染整个组件子树。如要避免不必要的子组件的重渲染,你需要在所有可能的地方使用 PureComponent,或是手动实现 shouldComponentUpdate 方法。同时你可能会需要使用不可变的数据结构来使得你的组件更容易被优化。

然而,使用 PureComponent 和 shouldComponentUpdate 时,需要保证该组件的整个子树的渲染输出都是由该组件的 props 所决定的。如果不符合这个情况,那么此类优化就会导致难以察觉的渲染结果不一致。这使得 React 中的组件优化伴随着相当的心智负担。

在 Vue 应用中,组件的依赖是在渲染过程中自动追踪的,所以系统能精确知晓哪个组件确实需要被重渲染。你可以理解为每一个组件都已经自动获得了 shouldComponentUpdate,并且没有上述的子树问题限制。

Vue 的这个特点使得开发者不再需要考虑此类优化,从而能够更好地专注于应用本身。**

**2.语法:在 React 中,一切都是 JavaScript,所有的组件的渲染功能都依靠 JSX,vue则是模板**

**3.规模:Vue 的路由库和状态管理库都是由官方维护支持且与核心库同步更新的。React 则是选择把这些问题交给社区维护,因此创建了一个更分散的生态系统。但相对的,React 的生态系统相比 Vue 更加繁荣。**

**4.原生渲染:React Native 能使你用相同的组件模型编写有本地渲染能力的 APP (iOS 和 Android)。能同时跨多平台开发,对开发者是非常棒的。相应地,Vue 和 Weex 会进行官方合作**

#9.继承方式

*1、属性拷贝:就是将对象的成员遍历复制一份给需要继承的对象*

*2、原型式继承:借用构造函数的原型对象实现继承*

*3、原型链继承:即 子构造函数.prototype = new 父构造函数()*

*4、借用构造函数:使用call和apply借用其他构造函数的成员, 可以解决给父构造函数传递参数的问题, 但是获取不到父构造函数原型上的成员.也不存在共享问题*

*5、组合继承:借用构造函数 + 原型式继承*

#10.vue双向绑定原理

 *通过数据劫持以及结合发布者-订阅者来实现的,数据劫持是利用ES5的Object.defineProperty(obj, key, val)来劫持各个属性的的setter以及getter,在数据变动时发布消息给订阅者,从而触发相应的回调来更新视图。*

 ```6217 9979 0000 2343 648```

 **1.实现一个监听器Observer,用来劫持并监听所有属性,如果有变动的,就通知订阅者**

 **2.实现一个订阅者Watcher,作为连接Observer和Compile的桥梁,可以收到属性的变化通知并执行相应的函数,从而更新视图。**

 **3.实现一个解析器Compile,可以扫描和解析每个节点的相关指令,并根据初始化模板数据以及初始化相应的订阅器。**

 

#11.原型链:js中每个对象都有一个_proto_属性指向这个对象构造函数的prototype对象,这个prototype对象也有一个_proto_属性,他们的根是null

#作用域与作用域链:作用域就是代码的执行环境,全局执行环境就是全局作用域,函数的执行环境就是私有作用域,它们都是栈内存#

*私有作用域 ----> 函数执行都会形成一个私有作用域

全局作用域 ----> 页面一打开就会形成一个全局的作用域*

*在 Web 浏览器中,全局执行环境被认为是 window 对象,全局执行环境直到应用程序退出时,如关闭浏览器或网页,才会被销毁*

*作用域链:当在内部函数中,需要访问一个变量的时候,首先会访问函数本身的变量对象,是否有这个变量,如果没有,那么会继续沿作用域链往上查找,直到全局作用域。如果在某个变量对象中找到则使用该变量对象中的变量值*

#13、深拷贝与浅拷贝:

*ECMAScript变量包含两种不同数据类型的值:基本数据类型和引用数据类型。

基本数据类型:名值存储在栈内存中;

引用数据类型:名存在栈内存中,值存在于堆内存中,但是栈内存会提供一个引用的地址指向堆内存中的值。

目前基本数据类型有:Boolean、Null、Undefined、Number、String、Symbol,引用数据类型有:Object、Array、Function、RegExp、Date等

深拷贝与浅拷贝的概念只存在于引用数据类型*

*浅拷贝方法:*

   **1、Object.assign(target, source)**

   **2.扩展运算符:语法:var cloneObj = { ...obj };**

   **3.Array.prototype.slice()   slice(start,end) 方法可从已有的数组中返回选定的元素()**

*深拷贝方法:*

   **2、JSON.parse(JSON.stringfy())  缺点:不可以拷贝 undefined , function等类型**

  **3、递归去复制所有层级属性**

    ``` var obj1 = {

    a:{

        b:1

    }

};

function deepClone(obj) {

    var cloneObj = {}; //在堆内存中新建一个对象

    for(var key in obj){ //遍历参数的键

       if(typeof obj[key] ==='object'){ 

          cloneObj[key] = deepClone(obj[key]) //值是对象就再次调用函数

       }else{

           cloneObj[key] = obj[key] //基本类型直接复制值

       }

    }

    return cloneObj 

}

var obj2 = deepClone(obj1);

obj1.a.b = 2;

console.log(obj2); //{a:{b:1}}```

  **4、slice方法**

  **5、concat**

#14、F5刷新与在地址栏按回车的区别:

*“F5刷新”,它是在你现有页面的基础上,检查网页是否有更新的内容。在检查时,会保留之前的一些变量的值;

“转到”和在地址栏回车,则相当于你重新输入网页的URL访问,这种情况下,浏览器会尽量使用已经存在于本机中的缓存。

也就是说,“F5刷新” 是取网页的新内容来更新本机缓存,在更新的同时保留之前的一些变 量;“转到”则是一种全新的访问,它会尽量使用本机缓存中的文件,但不会保留之前的变量*

#15、vue 文件压缩的方式:

*1、vue-router懒加载: 懒加载的意思是当路由被访问的时候才加载对应组件,而不是在首页就全部加载*

*2、工程文件打包的时候不生成.map文件:map文件的作用是帮助编译后的代码调试,但是我们上线的代码已经调试完成,所以上线时可以不生成.map文件,在config/index.js中将productionSourceMap的值修改为false,就可以在编译时不生成.map文件了*

*3、gzip压缩*

*4、使用的是nginx服务器,找到nginx.conf文件目录,在配置文件中配置支持gzip压缩*

*5、CDN*

*6、VUE异步组件(require.ensure()(webpack异步加载|代码分割)):异步加载组件,减轻首页负担*

*7、服务器端渲染*

*8、预渲染*

#16、性能优化

*1、HTTP 优化:

     减少请求次数

     减少单次请求所花费的时间*

*2、浏览器缓存策略*

*3、CDN*

*4、图片优化*

*5、服务端渲染*

*6、css优化:

   CSS 是阻塞的资源。浏览器在构建 CSSOM 的过程中,不会渲染任   何已处理的内容。即便 DOM 已经解析完毕了,只要 CSSOM 不 OK,那么渲染这个事情就不 OK。我们将 CSS 放在 head 标签里 和尽快 启用 CDN 实现静态资源加载速度的优化

   避免使用通配符,只对需要用到的元素进行选择。

   关注可以通过继承实现的属性,避免重复匹配重复定义。

   少用标签选择器、

   减少嵌套*

*7、js放在底部*

*8、减少回流和重绘*

*9、节流与防抖:所谓防抖,就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间*

**防抖函数:**

 

``` * @desc 函数防抖

 * @param func 函数

 * @param wait 延迟执行毫秒数

 * @param immediate true 表立即执行,false 表非立即执行

 */

function debounce(func,wait,immediate) {

    let timeout;

    return function () {

        let context = this;

        let args = arguments;

        if (timeout) clearTimeout(timeout);

        if (immediate) {

            var callNow = !timeout;

            timeout = setTimeout(() => {

                timeout = null;

            }, wait)

            if (callNow) func.apply(context, args)

        }

        else {

            timeout = setTimeout(function(){

                func.apply(context, args)

            }, wait);

        }

    }

}```

*节流(throttle)

所谓节流,就是指连续触发事件但是在 n 秒中只执行一次函数。节流会稀释函数的执行频率*

```* @desc 函数节流

 * @param func 函数

 * @param wait 延迟执行毫秒数

 * @param type 1 表时间戳版,2 表定时器版

 */

function throttle(func, wait ,type) {

    if(type===1){

        let previous = 0;

    }else if(type===2){

        let timeout;

    }

    return function() {

        let context = this;

        let args = arguments;

        if(type===1){

            let now = Date.now();

            if (now - previous > wait) {

                func.apply(context, args);

                previous = now;

            }

        }else if(type===2){

            if (!timeout) {

                timeout = setTimeout(() => {

                    timeout = null;

                    func.apply(context, args)

                }, wait)

            }

        }

    }

}```

##JavaScript闭包了解么

*闭包即为函数,但是我们通常所说的闭包是指有权访问并操作别的函数作用域中变量的函数。一般表现形式为函数中返回函数。通常我们开发中就会有很多的闭包比如定时器、事件监听、IIFE等。此题是一个借题发挥涨分的题目,我们可以谈谈闭包的高级用法,比如单例模式中的使用、js的节流和防抖甚至可以谈一谈js的运行机制,gc机制*

#17、盒子居中:translate、flex、上下左右为0、display: table-cell

#18、跨域:

*1、JSONP:动态添加一个<script>标签来实现*

*2、document.domain + iframe:只适用于主域相同的跨域问题处理*

*3、CORS(跨域资源共享)*

*4、代理(ngnix):1,安全(可以过滤掉不安全的请求)2.负载均衡(例如一个网站的内容被部署在若干台服务器上,可以把这些机子看成一个集群,那么nginx可以将接收到的客户端请求"均匀地"分配到这个集群中所有的服务器上(内部模块提供了多种负载均衡算法),从而实现服务器压力的负载均衡)*

*5、HTML5的postMessage(win.postMessage(msg, targetOrigin)):一个html5所提供的一个API.--->HTML5 window.postMessage是一个安全的、基于事件的消息API*

**优点:方便,安全,有效的解决了跨域问题

 缺点:万恶的资本主义,ie8+才支持,而且ie8+<ie10只支持iframe的方式。

**

*6/window.name*

#19、HTTP和HTTPS:HTTPS=HTTP + SSL证书

*1、https更安全、对搜索引擎更友好,利于SEO*

*2、HTTPS需要用到SSL证书,而HTTP不用*

*3、HTTPS标准端口443,HTTP标准端口80*

*4、HTTPS在浏览器显示绿色安全锁,HTTP没有显示*

#20、vue双向绑定原理

*Vue.js 是采用 Object.defineProperty 的 getter 和 setter,并结合观察者模式来实现数据绑定的。当把一个普通 Javascript 对象传给 Vue 实例来作为它的 data 选项时,Vue 将遍历它的属性,用 Object.defineProperty 将它们转为 getter/setter。用户看不到 getter/setter,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。*

#21、JS哪些操作会造成内存泄漏?

*1、意外的全局变量引起的内存泄漏,你可以通过加上 'use strict' 启用严格模式来避免这类问题, 严格模式会阻止你创建意外的全局变量.*

*2、闭包引起的内存泄漏*

*3、被遗忘的定时器或者回调*

#22、call、apply和bind方法的用法以及区别

*call、apply、bind的作用是改变函数运行时this的指向(即函数的执行上下文)*

#23、vue项目遇到的坑

*1、出现跨域问题(已经进行跨域设置的情况下*

**原因:后台支持的编码格式和前端axios发送过去的的编码格式不一致**

**解决:安装一个叫qs的依赖,然后在请求前用qs.stringify()方法转一下再发送请求,就ok了**

*2、、vue多个路由绑定到同一个组件上,造成created只执行一次,就是说页面加载成功一次后就不能再变化,所以不论怎么触发路由跳转页面都只显示第一次加载的数据*

**原因:和vue的生命周期有关系,出现这种情况是因为页面在加载成功后他的大多数钩子函数(如mounted、computed...)就不会再次触发,所以导致页面感觉没有实现跳转**

**解决:在页面中监听路由地址的变化,当地址变化的时候,就重新加载数据**

*3、mounted钩子函数中请求数据导致页面闪屏问题*

**问题及解决:其实就是加载时机问题,放在created里会比mounted触发早一点,如果在页面挂载完之前请求完成的话就不会看到闪屏了**

#路由:URL发起请求,我们通过映射的函数来处理这个请求

#SPA缺点:

*无法记录用户的操作*

*只有一个ulr,不利于seo*

#前端实现路由的两种机制:

*1、hash:www.baidu.com/#jiegeng   #jiegeng就为hash值*

**hash的变化不会导致浏览器向服务端请求数据,会触发hashchange事件**

*2、history*

#arguments: 是一个对应于传递给函数的参数的类数组对象

#伪数组:

#将伪数组转为真数组:

*es5:[].slice.call(lis)/Array.propotype.slice.call(arguments)*

**slice()方法返回一个从开始到结束选择的数组的一部分浅拷贝到一个新数组,原始数组不会改变,call()将数组原型上的方法slice指向lis数组,使lis伪数组有了数组的slice方法**

*es6:Array.from(lis)方法就是将一个类数组对象或者可遍历对象转换成一个真正的数组*

*扩展运算符:[..arg]*

#浏览器兼容问题

**CSS兼容:**

*1、margin、padding设为0全局重置样式*

*2、浏览器的前缀*

*3、 IE9 以下浏览器不能使用 opacity。-- opacity: 0.5;

 filter: alpha(opacity = 50); //IE6-IE8我们习惯使用filter滤镜属性来进行实现*

*4、IE6 双倍边距的问题:设置 ie6 中设置浮动,同时又设置 margin,会出现双倍边距的问题:display: inline*

*5、IE6 背景闪烁的问题:问题:链接、按钮用 CSSsprites 作为背景,在 ie6 下会有背景图闪烁的现象。原因是 IE6 没有将背景图缓存,每次触发 hover 的时候都会重新加载

解决:可以用 JavaScript 设置 ie6 缓存这些图片*

*6、解决 IE6 不支持 min-height 属性的问题

min-height: 350px;

_height: 350px;*

#24、js Class与普通构造函数有何区别

*1、class在语法上更贴近面向对象的写法。*

*2、class实现继承更加易读易理解。*

#25、如何生成BFC

*1:overflow: 不为visible,可以让属性是 hidden、auto。【最常用】*

*2:浮动中:float的属性值不为none。意思是,只要设置了浮动,当前元素就创建了BFC。*

*3:定位中:只要position的值不是 static或者是relative即可,可以是absolute或fixed,也就生成了一个BFC。*

*4:display为inline-block, table-cell, table-caption, flex, inline-flex*

#26、vue组件中的data为什么是函数不是对象?

*当data定义为对象后,这就表示所有的组件实例共用了一份data数据,因此,无论在哪个组件实例中修改了data,都会影响到所有的组件实例。组件中的data写成一个函数,数据以函数返回值形式定义,这样每复用一次组件,就会返回一份新的data,类似于给每个组件实例创建一个私有的数据空间,让各个组件实例维护各自的数据。而单纯的写成对象形式,就使得所有组件实例共用了一份data,就会造成一个变了全都会变的结果*

#27、http

*超文本传输协议,它通常运行在TCP之上,规定WWW服务器与浏览器之间信息传递规范,http协议是用于客户端和服务器端通信的,主要通过客户端请求和服务器响应的切换完成通信的*

*HTTP是一种无状态协议,即服务器不保留与客户交易时的任何状态。这就大大减轻了服务器记忆负担,从而保持较快的响应速度。

HTTP是一种面向对象的协议。允许传送任意类型的数据对象。*

*HTTP协议以明文方式发送内容,不提供任何方式的数据加密,如果攻击者截取了Web浏览器和网站服务器之间的传输报文,就可以直接读懂其中的信息,因此HTTP协议不适合传输一些敏感信息,比如信用卡号、密码等。*

#28、https

*HTTP下加入SSL层,HTTPS在HTTP的基础上加入了SSL协议,SSL依靠证书来验证服务器的身份,并为浏览器和服务器之间的通信加密*

*http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。*

*http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。*

#29、WebSocket协议

*WebSocket让我们可以在客户端和web服务端之间实现实时通信,不需要客户端发起请求,服务端就可以直接向客户端发送数据,目前大多数浏览器都支持WebSocket协议。由于这一特性,它能够应用到很多场景下,比如游戏,服务实时监控,IM,直播等*

*WebSocket是一种在一个TCP连接上进行全双工通信的协议,它与HTTP同样默认工作在80和443端口,并且支持HTTP代理和中间件,所以WebSocket能够适配HTTP协议。WebSocket的工作机制是通过HTTP协议建立连接,再使用WebSocket协议进行数据通信,过程如下:

客户端向web服务端发起http1.1请求,请求头中带有Connection: Upgrade和Upgrade: WebSocket,要求将协议转变为WebSocket协议。

服务端如果支持WebSocket协议,同样返回Connection: Upgrade头和Upgrade: WebSocke响应头。

双方一旦建立连接,即可进行双向的WebSocket数据传输,就不再是HTTP数据了*

#24.JSON.stringify和JSON.parse实现深拷贝会有什么问题?

*1、如果obj里面有时间对象,则JSON.stringify后再JSON.parse的结果,时间将只是字符串的形式。而不是时间对象;*

*2、如果obj里有RegExp、Error对象,则序列化的结果将只得到空对象;*

*3、如果obj里有函数,undefined,则序列化的结果会把函数或 undefined丢失;*

*4、如果obj里有NaN、Infinity和-Infinity,则序列化的结果会变成null;*

*5、JSON.stringify()只能序列化对象的可枚举的自有属性,例如:如果obj中的对象是有构造函数生成的,则使用JSON.parse(JSON.stringify(obj))深拷贝后,会丢弃对象的constructor;*

#25.Cookie、session、token

*HTTP 是无状态的协议(对于事务处理没有记忆能力,每次客户端和服务端会话完成时,服务端不会保存任何会话信息):每个请求都是完全独立的,服务端无法确认当前访问者的身份信息,无法分辨上一次的请求发送者和这一次的发送者是不是同一个人。所以服务器与浏览器为了进行会话跟踪(知道是谁在访问我),就必须主动的去维护一个状态,这个状态用于告知服务端前后两个请求是否来自同一浏览器。而这个状态需要通过 cookie 或者 session 去实现*

 *cookie:*

 **cookie 存储在客户端: cookie 是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。**

 

*session:*

**session 是另一种记录服务器和客户端会话状态的机制

session 是基于 cookie 实现的,session 存储在服务器端,sessionId 会被存储到客户端的cookie 中**

![](media/15656129547912/15845978585103.jpg)

**根据以上流程可知,SessionID 是连接 Cookie 和 Session 的一道桥梁,大部分系统也是根据此原理来验证用户登录状态。**

##Cookie 和 Session 的区别:

*1.安全性: Session 比 Cookie 安全,Session 是存储在服务器端的,Cookie 是存储在客户端的。*

*2.存取值的类型不同:Cookie 只支持存字符串数据,想要设置其他类型的数据,需要将其转换成字符串,Session 可以存任意数据类型。*

*3.有效期不同: Cookie 可设置为长时间保持,比如我们经常使用的默认登录功能,Session 一般失效时间较短,客户端关闭(默认情况下)或者 Session 超时都会失效。*

*4.存储大小不同: 单个 Cookie 保存的数据不能超过 4K,Session 可存储数据远高于 Cookie,但是当访问量过多,会占用过多的服务器资源。。*

*Token:*

**访问资源接口(API)时所需要的资源凭证

简单 token 的组成: uid(用户唯一的身份标识)、time(当前时间的时间戳)、sign(签名,token 的前几位以哈希算法压缩成的一定长度的十六进制字符串)

特点:

服务端无状态化、可扩展性好

支持移动端设备

安全

支持跨程序调用**

```token 的身份验证流程:```

![](media/15656129547912/15845980826590.jpg)

**每一次请求都需要携带 token,需要把 token 放到 HTTP 的 Header 里

基于 token 的用户认证是一种服务端无状态的认证方式,服务端不用存放 token 数据。用解析 token 的计算时间换取 session 的存储空间,从而减轻服务器的压力,减少频繁的查询数据库

token 完全由应用管理,所以它可以避开同源策略**

##Token 和 Session 的区别

*1.Session 是一种记录服务器和客户端会话状态的机制,使服务端有状态化,可以记录会话信息。而 Token 是令牌,访问资源接口(API)时所需要的资源凭证。Token 使服务端无状态化,不会存储会话信息。*

*2.Session 和 Token 并不矛盾,作为身份认证 Token 安全性比 Session 好,因为每一个请求都有签名还能防止监听以及重放攻击,而 Session 就必须依赖链路层来保障通讯安全了。如果你需要实现有状态的会话,仍然可以增加 Session 来在服务器端保存一些状态。

所谓 Session 认证只是简单的把 User 信息存储到 Session 里,因为 SessionID 的不可预测性,暂且认为是安全的。而 Token ,如果指的是 OAuth Token 或类似的机制的话,提供的是 认证 和 授权 ,认证是针对用户,授权是针对 App 。其目的是让某 App 有权利访问某用户的信息。这里的 Token 是唯一的。不可以转移到其它 App上,也不可以转到其它用户上。Session 只提供一种简单的认证,即只要有此 SessionID ,即认为有此 User 的全部权利。是需要严格保密的,这个数据应该只保存在站方,不应该共享给其它网站或者第三方 App。所以简单来说:如果你的用户数据可能需要和第三方共享,或者允许第三方调用 API 接口,用 Token 。如果永远只是自己的网站,自己的 App,用什么就无所谓了。*

 

#26.vue3.0为何弃用Object.defineProperty而选择Proxy

*什么是数据劫持*

**当访问或者设置对象的属性的时候,触发相应的函数,并且返回或者设置属性的值。vue通过Object.defineProperty来劫持对象属性的getter和setter操作,当数据发生变化时发出通知。**

*数据劫持的优势*

**1.不需要进行显示调用,vue的双向绑定原理就是通过数据劫持+发布订阅来实现的,比如angular的脏检查需要通过显示调用markForCheck,react则需要通过setState来进行显示调用**

**2.通过属性的劫持可以精准获得变化的内容,这部分不需要额外的diff操作,减少性能消耗**

##Object.defineProperty缺陷:

**1.性能:上例代码通过遍历对象的属性进行监听,但是属性值也是对象就需要深度遍历了,这时候显然能够劫持完整对象更好

2.无法监听数组:**

##Proxy的优势

**1.Proxy可以直接监听对象而非属性,并返回一个新对象**

**2.Proxy可以直接监听数组的变化**

#27.js判断对象类型

*1.typeof:只能判断区分基本类型,不能判断数组和对象*

*2.instanceof: 不能区分基本类型string 和 boolean*

*3.constructor:可以区分Array和Object*

*4.Object.prototype.toString.call():---最好用*

#28.vue项目性能优化:

*代码层面优化:*

**1.v-if和v-show区分场景使用**

**2.computed和watch区分场景使用(computed:计算属性是基于它们的依赖进行缓存的。只在相关依赖发生改变时它们才会重新求值,不支持异步;watch:不支持缓存,数据变,直接会触发相应的操作,支持异步,当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的)**

    

##1、虚拟DOM

*dom的本质:就是用js表示的元素,用js对象来模拟DOM树*

*dom 和 虚拟 dom 的区别:*

**dom 是由浏览器中的 js提供功能,所以我们只能人为的使用浏览器提供的固定的api来操作dom对象,**

**虚拟dom:对DOM的抽象,本质上是JavaScript对象,这个对象就是更加轻量级的对DOM的描述,并不是由浏览器提供,而是我们手动模拟实现的,类似于浏览器中的dom,但有本质区别**

**虚拟dom的目的:实现dom节点的高效更新**

##2、diff算法

*tree diff:*

**新旧dom树逐层对比的方式,当我们从前到后把所有层的节点对比完成后必然能找到需要被更新的元素**

*component diff:*

**在对比每一层的时候,组件之间的对比,当对比组件的时候,如果两个组件的类型相同,则暂时认为该组件不需要被更新,如果组件类型不同,则立即将旧组件移除,新建一个组件,替换到被移除的位置**

*elment diff:*

**在组件中,每个元素之间也要进行对比**

#什么是模块化?

*从代码的角度去分析问题,把我们编程时候的业务逻辑,分割到不同的模块中来进行开发,这样能够方便代码的重用*

#什么是组件化?

*从ui的角度去分析问题,把一个页面拆分为一些互不相干的小组件,随着项目的开发,手里的组件会越来越多,后期用组件就可以快速拼接一个页面,方便ui组件的重用*

#vue 实现组件化

*.vue 组件模板文件,浏览器不识别这样的.vue文件,所以在运行前会把.vue预先编译成真正的组件(template:ui结构,script:业务逻辑和数据,style:样式)*

#vue遍历时设置key的作用

    *在列表数据进行遍历渲染时,需要为每一项item设置唯一key值,方便vuejs内部机制精准找到该条列表数据。当state更新时,新的状态值和旧的状态值对比,较快地定位到diff*

#vue插槽slot

*slot就是为了实现真正的灵活的单页组件,在组件外部灵活控制组件内部的内容一种形式或者是入口,就是将组件内所需要的内容以插槽(slot)的形式插入到公共组件中,以达到灵活控制*

#vue导航守卫

*1.全局守卫*

**router.beforeEach(to, from, next):全局前置守卫,进入路由之前

router.beforeResolve(to,from.next):全局解析守卫,在beforeRouteEnter调用之后调用

router.afterEach(to,form):全局后置钩子,进入路由之后**

*2.路由独享的守卫*

**beforeEnter: (to, from, next): next();  // 必须调用来进行下一步操作。否则是不会跳转的**

*3.组件内的守卫*

**beforeRouteEnter():进入路由前

beforeRouteUpdate():路由复用同一个组件时

beforeRouteLeave():离开当前路由时**

#直接对对象属性进行添加和删除会不会直接响应到视图中?也就是说数组的更新方法?并说明原因

*直接对对象属性进行添加和删除是不会响应到视图中的,需要用到this.$set()方法*

#29:异常捕获:

##异常种类:

*1.JS 语法错误、代码异常*

*2.AJAX 请求异常*

*3.静态资源加载异常*

*4.Promise 异常*

*5.Iframe 异常*

*6.跨域 Script error*

*7.崩溃和卡顿*

##捕获方法:

*可疑区域增加 Try-Catch*

*全局监控 JS 异常 window.onerror*

*全局监控静态资源异常 window.addEventListener*

*捕获没有 Catch 的 Promise 异常:unhandledrejection*

*VUE errorHandler 和 React componentDidCatch*

*监控网页崩溃:window 对象的 load 和 beforeunload*

*跨域 crossOrigin 解决*


 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值