面试题

1、内存泄露
内存泄漏指任何对象在您不再拥有或需要它之后仍然存在。
垃圾回收器定期扫描对象,并计算引用了每个对象的其他对象的数量。如果一个对象的引用数量为 0(没有其他对象引用过该对象),或对该对象的惟一引用是循环的,那么该对象的内存即可回收。
1. setTimeout 的第一个参数使用字符串而非函数的话,会引发内存泄漏。
2. 闭包
3. 控制台日志
4. 循环(在两个对象彼此引用且彼此保留时,就会产生一个循环)
2、cookie的弊端
cookie虽然在持久保存客户端数据提供了方便,分担了服务器存储的负担,但还是有很多局限性的。
第一:每个特定的域名下最多生成20个cookie
1.IE6或更低版本最多20个cookie
2.IE7和之后的版本最后可以有50个cookie。
3.Firefox最多50个cookie
4.chrome和Safari没有做硬性限制
IE和Opera 会清理近期最少使用的cookie,Firefox会随机清理cookie。
cookie的最大大约为4096字节,为了兼容性,一般不能超过4095字节。
IE 提供了一种存储可以持久化用户数据,叫做 userData,从IE5.0就开始支持。每个数据最多128K,每个域名下最多1M。这个持久化数据放在缓存中,如果缓存没有清理,那么会一直存在。
优点:极高的扩展性和可用性
1.通过良好的编程,控制保存在cookie中的session对象的大小。
2.通过加密和安全传输技术(SSL),减少cookie被破解的可能性。
3.只在cookie中存放不敏感数据,即使被盗也不会有重大损失。
4.控制cookie的生命期,使之不会永远有效。偷盗者很可能拿到一个过期的cookie。
缺点:
1.`Cookie`数量和长度的限制。每个domain最多只能有20条cookie,每个cookie长度不能超过4KB,否则会被截掉。
2.安全性问题。如果cookie被人拦截了,那人就可以取得所有的session信息。即使加密也与事无补,因为拦截者并不需要知道cookie的意义,他只要原样转发cookie就可以达到目的了。
3.有些状态不可能保存在客户端。例如,为了防止重复提交表单,我们需要在服务器端保存一个计数器。如果我们把这个计数器保存在客户端,那么它起不到任何作用。
3、css盒子模型
①盒模型: 内容(content)、填充(padding)、边界(margin)、 边框(border)
②类型: IE 盒子模型、标准 W3C 盒子模型;
③两种盒模型的主要区别是:标准盒模型的宽高是值内容宽高(content)
 
④而IE盒模型的宽高是指content+padding+border。
 
⑤设置盒模型的方式是:设置box-sizing
    box-sizing:content-box  标准盒模型
    box-sizing:border-box IE盒模型
 
⑥盒子模型的定位
   网页默认的布局方式
   浮动
   Position定位
4、css3的新特性
1. CSS3实现圆角(border-radius),阴影(box-shadow),
2. 对文字加特效(text-shadow、),线性渐变(gradient),旋转(transform)
3. transform:rotate(9deg) scale(0.85,0.90) translate(0px,-30px) skew(-9deg,0deg);// 旋转,缩放,定位,倾斜
4. 增加了更多的CSS选择器  多背景 rgba
5. 在CSS3中唯一引入的伪类是 ::selection.
6. 媒体查询,多栏布局
7. border-image
5、BFC的理解
BFC,块级格式化上下文,一个创建了新的BFC的盒子是独立布局的,盒子里面的子元素的样式不会影响到外面的元素。在同一个 BFC 中的两个毗邻的块级盒在垂直方向(和布局方向有关系)的
 margin 会发生折叠。
W3C CSS 2.1 规范中的一个概念,它决定了元素如何对其内容进行布局,以及与其他元素的关系和相互作用。
6、HTML5的新特性
新特性:
HTML5 现在已经不是 SGML 的子集,主要是关于图像,位置,存储,多任务等功能的增加。
1. 拖拽释放(Drag and drop) API 
2. 语义化更好的内容标签(header,nav,footer,aside,article,section)
3. 音频、视频API(audio,video)
4. 画布(Canvas) API
5. 地理(Geolocation) API
6. 本地离线存储 localStorage 长期存储数据,浏览器关闭后数据不丢失;
7. sessionStorage 的数据在浏览器关闭后自动删除
8. 表单控件,calendar、date、time、email、url、search  
9. 新的技术webworker, websocket, Geolocation
移除的元素:
1. 纯表现的元素:basefont,big,center,font, s,strike,tt,u;
2. 对可用性产生负面影响的元素:frame,frameset,noframes;
7、如何对网站的文件和资源进行优化
1. 文件合并
2. 文件最小化/文件压缩
3. 使用 CDN 托管
4. 缓存的使用(多个域名来提供缓存)
5. 其他
8、减少页面加载时间的方法
1. 优化图片 
2. 图像格式的选择(GIF:提供的颜色较少,可用在一些对颜色要求不高的地方) 
3. 优化CSS(压缩合并css,如 margin-top, margin-left...) 
4. 网址后加斜杠(如www.campr.com/目录,会判断这个目录是什么文件类型,或者是目录。) 
5. 标明高度和宽度(如果浏览器没有找到这两个参数,它需要一边下载图片一边计算大小,如果图片很多,浏览器需要不断地调整页面。这不但影响速度,也影响浏览体验。 
当浏览器知道了高度和宽度参数后,即使图片暂时无法显示,页面上也会腾出图片的空位,然后继续加载后面的内容。从而加载时间快了,浏览体验也更好了) 
6. 减少http请求(合并文件,合并图片)
9、null和undefined的区别
null是一个表示"无"的对象,转为数值时为0
undefined是一个表示"无"的原始值,转为数值时为NaN
当声明的变量还未被初始化时,变量的默认值为undefined
null用来表示尚未存在的对象,常用来表示函数企图返回一个不存在的对象
undefined表示 “缺少值”,就是此处应该有一个值,但是还没有定义。典型用法是:
1. 变量被声明了,但没有赋值时,就等于 undefined
2. 调用函数时,应该提供的参数没有提供,该参数等于 undefined
3. 对象没有赋值的属性,该属性的值为 undefined
4. 函数没有返回值时,默认返回 undefined
null表示“没有对象”,即该处不应该有值。典型用法是:
1. 作为函数的参数,表示该函数的参数不是对象
2. 作为对象原型链的终点
10、解决跨域问题
1. jsonp(jsonp 的原理是动态插入 script 标签)
2. 服务器上设置代理页面
3. document.domain + iframe
4. window.name、window.postMessage
11、http与https的区别
http传输的数据都是未加密的,也就是明文的,网景公司设置了SSL协议来对http协议传输的数据进行加密处理,简单来说https协议是由http和ssl协议构建的可进行加密传输和身份认证的网络协议
,比http协议的安全性更高。主要的区别如下:
Https协议需要ca证书,费用较高。
http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。
使用不同的链接方式,端口也不同,一般而言,http协议的端口为80,https的端口为443
http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。
12、tcp三次握手
1、客户端向服务器端发送SYN报文seq(x),请求连接,等待服务器端确认
2、服务器端接收到客户端的SYN报文,向客户端发送确认信息 SYN seq(y)+ack(x+1)
3、客户端收到服务器端的报文,向服务器端发送ACK )报文ack=y+1,这个报文段发送完毕以后,客户端和服务器端都进入established状态,完成TCP三次握手。
13、.call()和.apply()的区别
改变this的指向,传参问题,动态改变某个类的某个方法的运行环境
14、内存泄露
内存泄漏指任何对象在您不再拥有或需要它之后仍然存在。
垃圾回收器定期扫描对象,并计算引用了每个对象的其他对象的数量。如果一个对象的引用数量为 0(没有其他对象引用过该对象),或对该对象的惟一引用是循环的,那么该对象的内存即可回收。
1. setTimeout 的第一个参数使用字符串而非函数的话,会引发内存泄漏。
2. 闭包
3. 控制台日志
4. 循环(在两个对象彼此引用且彼此保留时,就会产生一个循环)
15、Node 的优缺点
优点:
1. 因为Node是基于事件驱动和无阻塞的,所以非常适合处理并发请求,因此构建在Node上的代理服务器相比其他技术实现(如Ruby)的服务器表现要好得多。
2. 与Node代理服务器交互的客户端代码是由javascript语言编写的,因此客户端和服务器端都用同一种语言编写,这是非常美妙的事情。
缺点:
1. Node是一个相对新的开源项目,所以不太稳定,它总是一直在变。
2. 缺少足够多的第三方库支持。看起来,就像是Ruby/Rails当年的样子(第三方库现在已经很丰富了,所以这个缺点可以说不存在了)。
16、性能优化
1. 减少http请求次数:CSS Sprites, JS、CSS 源码压缩、图片大小控制合适;网页 Gzip,CDN 托管,data 缓存 ,图片服务器
2. 前端模板 JS + 数据,减少由于HTML标签导致的带宽浪费,前端用变量保存 AJAX 请求结果,每次操作本地变量,不用请求,减少请求次数
3. 用 innerHTML 代替 DOM 操作,减少 DOM 操作次数,优化 javascript 性能
4. 当需要设置的样式很多时设置 className 而不是直接操作 style
5. 少用全局变量、缓存DOM节点查找的结果。减少 IO 读取操作
6. 避免使用 CSS Expression(css表达式)又称 Dynamic properties(动态属性)
7. 图片预加载,将样式表放在顶部,将脚本放在底部,加上时间戳
17、JavaScript继续的6种方法
1. 原型链继承
2. 借用构造函数继承
3. 组合继承(原型+借用构造)
4. 原型式继承
5. 寄生式继承
6. 寄生组合式继承
18、Ajax的过程
1. 原型链继承
2. 借用构造函数继承
3. 组合继承(原型+借用构造)
4. 原型式继承
5. 寄生式继承
6. 寄生组合式继承
19、同源策略
概念:
同源策略是客户端脚本(尤其是Javascript)的重要的安全度量标准。它最早出自Netscape Navigator2.0,其目的是防止某个文档或脚本从多个不同源装载。
这里的同源策略指的是:协议,域名,端口相同,同源策略是一种安全协议,指一段脚本只能读取来自同一来源的窗口和文档的属性。
20、get、post的区别,什么时候用post
GET:一般用于信息获取,使用URL传递参数,对所发送信息的数量也有限制,一般在2000个字符
POST:一般用于修改服务器上的资源,对所发送的信息没有限制
GET方式需要使用 Request.QueryString 来取得变量的值
POST方式通过 Request.Form 来获取变量的值
也就是说 Get 是通过地址栏来传值,而 Post 是通过提交表单来传值。
在以下情况中,请使用 POST 请求:
1. 无法使用缓存文件(更新服务器上的文件或数据库)
2. 向服务器发送大量数据(POST 没有数据量限制)
3. 发送包含未知字符的用户输入时,POST 比 GET 更稳定也更可靠
21、node的适用场景
1. 高并发
2. 聊天
3. 实时消息推送 
22、JavaScript 原型以及原型链,有什么特点
1. 原型对象也是普通的对象,是对象一个自带隐式的 __proto__ 属性,原型也有可能有自己的原型,如果一个原型对象的原型不为 null 的话,我们就称之为原型链
2. 原型链是由一些用来继承和共享属性的对象组成的(有限的)对象链
23、js 浅拷贝和深拷贝
浅拷贝的方法:
 (1)for···in只循环第一层
 (2)Object.assign方法
 (3)直接用=赋值
    let a=[0,1,2,3,4],
    b=a;
    console.log(a===b);
    a[0]=1;
    console.log(a,b);
    
深拷贝的方法:
 (1)采用递归去拷贝所有层级属性
 (2) 通过JSON对象来实现深拷贝   //自带的方法无法拷贝,会undefined
 (3)通过jQuery的extend方法实现深拷贝
 (4)lodash函数库实现深拷贝
 (5)Reflect法
 (6)手动实现深拷贝
 (7)如果对象的value是基本类型的话,也可以用Object.assign来实现深拷贝,但是要把它赋值给一个空对象


vue

1.vue性能优化的几种方案
1.正确的选择v-if和v-show的使用,v-if有更高的切换消耗,v-show有更高的初始消耗

2.路由懒加载:当页面很多,组件很多的时候,SPA页面在首次加载的时候,就会变的很慢。这是因为vue首次加载的时候把可能一开始看不见的组件也一次加载了,
  这个时候就需要对页面进行优化,就需要异步组件了。

3.缓存:spa页面采用keep-alive缓存组件
4.图片懒加载:提高页面加载速度,不在可视区域内的图片先不加载,只有滚动到可视区域的时候才加载。一般借助外部插件如 vue-lazyload。
  使用只需要npm install vue-lazyload然后页面引入即可使用。
5.SEO优化: ssr服务端渲染
6.打包优化:对于一些过大的包采取cdn引入文件的方式而不是直接下载到本地。
2.v-show和v-if谁的性能更高
v-show本质就是通过控制css中的display设置为none,控制隐藏,只会编译⼀次;v-if是动态的向DOM树内添加或者删除DOM元素,若初始值为false,就不会编译了。
⽽且v-if不停的销毁和创建⽐较消耗性能。所以如果要频繁切换那么v-show性能更高,如果不是频繁切换,v-if性能更高

3.vue之间的数据传递
父到子:props
子到父:$emit自定义事件
复杂组件的传递:通过vuex

4.单文件组件中如何让样式只在当前组件生效
在组件中的style前面加上scoped

5.vue中的生命周期(钩子函数)
共有8+2个钩子函数 基本的有8个,keep-alive中有2个

beforeCreate(创建前) / created(创建后) / beforeMount(挂载前) / mounted(挂载后) beforeUpdate(更新前)/ updated(更新后)
 /beforeDestroy(销毁前)/ destroyed(销毁后)

其中第一次加载页面会触发 beforeCreate, created, beforeMount, mounted 这几个钩子

另外在keep-alive中,vue新增了两个钩子函数
activated:因为使用了keep-alive的组件会被缓存,所以created,mounted这种的钩子函数只会执行一次, 如果我们的子组件需要在每次加载的时候进行某些操作,可以使用activated钩子触发。
deactivated:组件被移除时使用。

6.vue父子组件生命周期的执行顺序
加载渲染过程
父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted

子组件更新过程
父beforeUpdate->子beforeUpdate->子updated->父updated

父组件更新过程
父beforeUpdate->父updated

销毁过程
父beforeDestroy->子beforeDestroy->子destroyed->父destroyed

7.在vue中如何获取DOM元素
给元素添加ref属性 通过this.$refs.domName获取

8.key的作用
需要使用key来给每个节点做一个唯一标识,Diff算法就可以正确的识别此节点。
作用主要是为了高效的更新虚拟DOM。

9.$nextTick的使用场景(作用)
因为vue中数据更新是异步的,当你修改了data的值然后马上获取这个dom元素的值,是不能获取到更新后的值,
你需要使用$nextTick这个回调,让修改后的data值渲染更新到dom元素之后在获取,才能成功。

10.v-if和v-for的优先级
v-if 与 v-for 一起使用时,v-for 具有比 v-if 更高的优先级,这意味着 v-if 将分别重复运行于每个 v-for 循环中。所以,不推荐v-if和v-for同时使用。如果非要一起用,可以把v-if放到外层元素,或者不用v-if,先在计算属性中筛选出数据,然后在v-for

11.v-model的原理
vue 双向数据绑定是通过 数据劫持 结合 发布订阅模式的方式来实现的, 也就是说数据和视图同步,数据发生变化,视图跟着变化,视图变化,数据也随之发生改变;
核心:关于VUE双向数据绑定,其核心是 Object.defineProperty()方法。

12.什么是mvvm
MVVM 将数据双向绑定(data-binding)作为核心思想,View 和 Model 之间没有联系,它们通过 ViewModel 这个桥梁进行交互。
Model 和 ViewModel 之间的交互是双向的,因此 View 的变化会自动同步到 Model,而 Model 变化也会立即反映到 View 上显示。
当用户操作 View,ViewModel 感知到变化,然后通知 Model 发生相应改变;反之当 Model 发生改变,ViewModel 也能感知到变化,使 View 作出相应更新。

13.如何优化SPA应用的首屏加载速度慢的问题
将公用的JS库通过script标签外部引入,减小app.bundel的大小,让浏览器并行下载资源文件,提高下载速度;
在配置 路由时,页面和组件使用懒加载的方式引入,进一步缩小 app.bundel 的体积,在调用某个组件时再加载对应的js文件;
加一个首屏 loading 图,提升用户体验;

14.vue路由的两种模式,hash与history的区别
hash —— 即地址栏 URL 中的 # 符号(此 hash 不是密码学里的散列运算)。
比如这个 URL:ABC Home Page - ABC.com 的值为 #/hello。它的特点在于:hash 虽然出现在 URL 中,但不会被包括在 HTTP 请求中,对后端完全没有影响,因此改变 hash 不会重新加载页面。

history —— 利用了 HTML5 History Interface 中新增的 pushState() 和 replaceState() 方法。(需要特定浏览器支持)
这两个方法应用于浏览器的历史记录栈,在当前已有的 back、forward、go 的基础之上,它们提供了对历史记录进行修改的 功能。只是当它们执行修改时,虽然改变了当前的 URL,
但浏览器不会立即向后端发送请求。
因此可以说,hash 模式和 history 模式都属于浏览器自身的特性,Vue-Router 只是利用了这两个特性(通过调用浏览器提供 的接口)来实现前端路由。

注意!!!history模式下,前端的url必须和实际向后端发起请求的url 一致,如http://www.abc.com/book/id 。如果后端缺少对/book/id 的路由处理,将返回404错误。
刷新也会报404因为会实际去请求数据。 (需要后端进行配置。vue官网有介绍)

15.如何解决vuex数据刷新丢失的问题
因为store里的数据是保存在运行内存中的,当页面刷新时,页面会重新加载vue实例,store里面的数据就会被重新赋值

如何解决:

一种是state里的数据全部是通过请求来触发action或mutation来改变(不推荐,当vuex数据很多项目很大的时候不适用)

一种是将state里的数据保存一份到本地存储(localStorage、sessionStorage、cookie)中 (推荐)

16.vue中如何实现跨域访问
1.开发环境:配置vue.config.js proxy代理
2.生产环境:配置nginx代理


1.vue的原理?





关键词: 虚拟DOM树+访问器属性

解释一下:响应式原理?


当你把一个普通的 JavaScript 对象传入 Vue 实例作为 data 选项,Vue 将遍历此对象所有的 property,并使用 Object.defineProperty把这些 property 全部转为 getter/setter这些 getter/setter 对用户来说是不可见的,但是在内部它们让 Vue 能够追踪依赖,在 property 被访问和修改时通知变更,每个组件实例都对应一个 watcher 实例,它会在组件渲染的过程中把“接触”过的数据 property 记录为依赖。之后当依赖项的 setter 触发时,会通知 watcher,从而使它关联的组件重新渲染。



vue为什么不支持IE8及更低版本?


Object.defineProperty` 是 ES5 中一个无法 shim 的特性,这也就是 Vue 不支持 IE8 以及更低版本浏览器的原因。



2. vue有哪些缺点



Vue 不能检测数组和对象的变化




3.为什么vue不能检测对象的变化


对于对象, Vue 无法检测 property 的添加或移除,由于 Vue 会在初始化实例时对 property 执行 getter/setter 转化,所以 property 必须在 data 对象上存在才能让 Vue 将它转换为响应式的.



追问:那如何解决上述问题?


使用this.$set(this.someObject,'b',2) 添加新的属性
使用this.$delete(this.someObject,'b') 删除旧属性



4.讲一下 $set 的实现原理


1、如果目标是数组,使用 vue 实现的变异方法 splice 实现响应式
2、如果目标是对象,判断属性存在,即为响应式,直接赋值
3、如果 target 本身就不是响应式,直接赋值
4、如果属性不是响应式,则调用 defineReactive 方法进行响应式处理



核心代码如下


export function set(target: Array | Object, key: any, val: any): any {
  // target 为数组
  if (Array.isArray(target) && isValidArrayIndex(key)) {
   // 修改数组的长度, 避免索引>数组长度导致splice()执行有误
    target.length = Math.max(target.length, key);
    // 利用数组的splice变异方法触发响应式
    target.splice(key, 1, val);
    return val;
  }

  // target为对象, key在target或者target.prototype上 且必须不能在 Object.prototype 上,直接赋值
  if (key in target && !(key in Object.prototype)) {
    target[key] = val;
    return val;
  }

  // 以上都不成立, 即开始给target创建一个全新的属性
  // 获取Observer实例
  const ob = (target: any).__ob__;
  // target 本身就不是响应式数据, 直接赋值
  if (!ob) {
    target[key] = val;
    return val;
  }

  // 进行响应式处理
  defineReactive(ob.value, key, val);
  ob.dep.notify();
  return val;
}



5.new Vue()实例中,data 可以直接是一个对象,为什么在 vue 组件中,data 必须是一个函数呢?

关键词:复用+污染 + 函数返回 + 数据拷贝


因为组件是可以复用的,JS 里对象是引用关系,如果组件 data 是一个对象,那么子组件中的 data 属性值会互相污染,产生副作用。所以一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝。new Vue 的实例是不会被复用的,因此不存在以上问题。



6.computed 和 watch 有什么区别?







computed 计算属性 :
依赖其它属性值,只有它依赖的属性值发生改变,下一次获取 computed 的值时才会重新计算 computed 的值,如果和上次计算结果不一致,重新渲染页面。
watch 侦听器 : 更多的是「观察」的作用,无缓存性,类似于某些数据的监听回调,每当监听的数据变化时都会执行回调进行后续操作。



追问:computed 和 watch 应用场景?
关键词  computed+缓存


computed :当我们需要进行数值计算,并且依赖于其它数据时,应该使用 computed,因为可以利用 computed 的缓存特性,避免每次获取值时,都要重新计算。
watch: 当我们需要在数据变化时执行的操作时使用(如调用其它函数)



追问 :能使用箭头函数定义computed和watch吗?


不应该使用箭头函数来定义 watcher 函数,理由是箭头函数绑定了父级作用域的上下文,所以 this 将不会按照期望指向 Vue 实例,为undefined



7.MVC和MVVM的原理

MVC






视图(View):用户界面。
控制器(Controller):业务逻辑
模型(Model):数据保存



实现流程


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



MVVM


视图(View):用户界面。
视图模型(VM):双向数据绑定
模型(Model):数据+业务




在MVVM架构下,View 和 Model 之间并没有直接的联系,而是通过ViewModel进行交互. Model 和 ViewModel 之间的交互是双向的, 因此View 数据的变化会同步到Model中,而Model 数据的变化也会立即反应到View 上。









8.vue数据绑定是双向还是单向的


Vue 在不同组件间强制使用单向数据流。这使应用中的数据流更加清晰易懂。



9.v-model双向绑定的原理?


v-model 本质上不过是语法糖。它负责监听用户的输入事件以更新数据.



原理如下:


Object.defineproperty()重新定义(set方法)对象设置属性值和(get方法)获取属性值的操纵来实现的.
1.实现一个监听器Observer,用来劫持并监听所有属性,如果有变动的,就通知订阅者。
2.实现一个订阅者Watcher,可以收到属性的变化通知并执行相应的函数,从而更新视图。
3.实现一个解析器Compile,可以扫描和解析每个节点的相关指令,并根据初始化模板数据以及初始化相应的订阅器。



9.全局导航钩子函数应用场景?


vue router.beforeEach(全局前置守卫)router.beforeEach 是页面加载之前(before each)意思是在 每次每一个路由改变的时候都得执行一遍.
vue router.afterEach(全局后置守卫),相反router.afterEach是页面加载之后.



应用场景:



可进行一些页面跳转前处理,例如判断需要登录的页面进行拦截,做登录跳转!
2.进入页面登录判断、管理员权限判断、浏览器判断




10 .v-if和v-for在同一个标签中的执行顺序?


v-for 比 v-if 优先级高,如果每一次都需要遍历整个数组,将会影响速度注意v-for 遍历避免同时使用 v-if



如果需要使用判断,建议使用计算属性


<ul>  <li    v-for="user in activeUsers"    :key="user.id">    {{ user.name }}  </li></ul>

computed: {  activeUsers: function () {    return this.users.filter(function (user) {    return user.isActive    })  }}



10.路由独享的守卫(路由内钩子)

路由独享的守卫(路由内钩子)你可以在路由配置上直接定义 beforeEnter 守卫:


const router = new VueRouter({ routes: [   
 {    
    path: '/foo',     
    component: Foo,    
    beforeEnter: (to, from, next) => {         
    // 处理
    ...
    next()     
    }
    }  ]



11.vue-loader是什么?它有什么作用?


 解析和转换 .vue 文件,提取出其中的逻辑代码 script、样式代 码 style、以及 HTML 模版 template,再分别把它们交给对应的 Loader 去处理。



12.vue中怎么重置data?


this .$options.data可以获取到组件初始化状态下的datathis.$data获取当前状态下的data// 将数据拷贝到this.$data中即可Object.assign(this.$data, this.$options.data())



13.在vue项目中如果methods的方法用箭头函数定义结果会怎么样?


因为箭头函数默绑定父级作用域的上下文,所以不会绑定vue实例, 在严格模式下this是undefined,在非严格模式下指向window



14.vue怎么实现强制刷新组件?


1.调用强制刷新方法 this.$forceUpdate()



给模板上绑定key值,通过修改key值,实现组件刷新<SomeComponent :key="theKey"/>//选项里绑定datadata(){  return{      theKey:0  }}//刷新key达到刷新组件的目的theKey++;

15.如何在子组件中访问父组件的实例?


通过this.parent.event来调用父组件的方法
2:在子组件里用$emit向父组件触发一个事件,父组件监听这个事件



3:父组件把方法传入子组件中,在子组件里直接调用这个方法父组件如何调用子组件的方法?给子组件设置属性ref
<子组件 ref="name" />可以在子组件中加上ref,然后通过this.$refs.ref.method调用

16.vue组件里写的原生addEventListeners监听事件,要手动去销毁吗?为什么?


需要, Vue不会主动移除监听事件, 多次进入组件,事件会绑定多次,另一方面是函数没释放会内存溢出.



17.组件中写name选项有什么作用?


a.项目使用keep-alive时,可搭配组件name进行缓存过滤b.DOM做递归组件时需要调用自身name
c.vue-devtools调试工具里显示的组见名称是由vue中组件name决定的



18.<template></template>有什么用?


当做一个不可见的包裹元素,减少不必要的DOM元素,整个结构会更加清晰。使用场景主要用于分组的条件判断和列表渲染。结合v-for、v-if等一起使用,插槽时使用



19 .vue组件之间的通信都有哪些?


父子组件传值



通过props属性传值
通过
on传值
( 
children ) / $refs


兄弟组件传值
1.Vuex
2.Bus
跨级组件传值



provide/inject


listeners

20.route和router有什么区别?


route:代表当前路由信息对象,可以获取到当前路由的信息参数router:代表路由实例的对象,包含了路由的跳转方法,钩子函数等



21.怎样动态加载路由?


通过router.addRoutes方法可以动态加载路由.




 let router=new VueRouter({
       routes:[           
             {path:'/product',component:a,name:'product'} 
        ]
        });  
      router.addRoutes([     
         {path:'/user',component:c,name:'user'},       
         {path:'/address',component:address,name:'address'}  
       ]);



22.说说active-class是哪个组件的属性?


active-class是vue-router模块的router-link组件中的属性,用来设置选中连接的样式.



23.为什么vue使用异步更新组件?


收集当前的改动一次性批量更新,为了节省diff开销.



24.怎么缓存当前的组件?缓存后怎么更新?





1.通过keep-alive组件缓存需要缓存的组件


 <keep-alive includes="组件1name,组件2name">
      <router-view>
  </keep-alive>



2.当组件激活后,会触发钩子函数actived,在这个钩子函数中,做数据更新.

25.vue怎么获取DOM节点?


为组件定义ref属性<input ref="myInput">通过this.$refs.myInput 就可以获取dom节点.



26.vuex中actions和mutations有什么区别?


1.mutations可以直接修改state,但只能包含同步操作,同时,只能通过提交commit调用.
2.actions可以包含异步操作,通过store.dispatch触发,不能直接修改数据,需要调用commit去修改数据.



27. 怎么监听vuex数据的变化?


通过watch监听数据的变化




watch:{ 
     '$store.state.test':function(value){    
          console.log('数据修改了',value) 
      }}



28.开启vuex中的严格模式有什么好处?


主要用户防止不合理的改变状态值如:this.$.store.state.list = [],这样就会抛出异常



A.在严格模式下,无论何时发生了状态变更且不是由 mutation 函数引起的,将会抛出错误。这能保证所有的状态变更都能被调试工具跟踪到。
B. 不要在发布环境下启用严格模式!严格模式会深度监测状态树来检测不合规的状态变更——请确保在发布环境下关闭严格模式,以避免性能损失。

如何使用?


const store = new Vuex.Store({  
  // 让构建工具自动帮我们处理
  strict: process.env.NODE_ENV !== 'production'
  })



30.你了解双向绑定的计算属性的应用场景吗?


<input type="text" v-model="username">



如果我们想要监听用户输入变化,我们首先会想到下面的方法


<input type="text" v-model="username" @input="onChange">



其实我们可以使用双向绑定的计算属性来实现


 data() {    
   return {      _username:''    }; 
 },  computed:{   
  username:{     
  get(){        
      return this._username     
    },     
  set(value){         // 监听数据变化      
      console.log('监听数据变化',value)   
      this._username = value   }
    }
  }



当我们使用了Vuex时,并且开启了严格模式,那么我们就不能直接绑定状态值了, 在用户输入时,v-model 会试图直接修改状态name的值,这样会抛出异常<input v-model="$store.state.name">这个时候我们需要使用双向绑定的计算属性来解决这个问题


<input v-model="name">
computed: {  
  name: {    
   get () {     
       return this.$store.state.name   
   }, 
   set (value) {      
     this.$store.commit('updateName', value)  
    } 
 }}



30.vue中的指令v-on如何绑定多个属性?


v-on={  事件名:绑定的自定义回调函数}




  <input  type="text"  v-on="{input:onInput,focus:onFocus}"/>



31.vue中使用delete删除对象的属性,页面会更新吗?


delete this.list[1] 页面不会更新, Vue不能检测到 property 被删除那么如何在删除元素或者对象属性时,可以触发更新视图? this.$delete(this.list,1)



32.watch怎么深度监听对象变化?


 data() {    
      return {     
         data:{},    
         user:{      
            info:{  name:123        }   
          }
       };
      }



比如我们要对user.info 属性进行监听,如果info属性有任何更改触发通知


watch:{     'user.info':{    
   handler(value){     
     console.log("数据变化",value)  
     }
   }
  }



此时我们调用

this.user.info.name = "8888888"handle方法不会被触发.这个user.info是一个对象
Vue只响应对象的地址变化进行响应.
如果我们需要让Vue对整个info里面的属性变化,进行监听,
就需要开启深度监听属性deep:true


watch:{   
  'user.info':{       
   handler(value){       
   console.log("数据变化",value) 
  },     
   deep:true
  }
 }



33 .vue组件会在什么时候下被销毁?


1.页面关闭、
2.路由跳转、
3.v-if为false
4.改变key值



33.怎么使css样式只在当前组件中生效


给style标签添加scoped属性, 通过该属性,可以使得组件之间的样式不互相污染<style scoped> </style>



原理vue中的scoped属性的效果主要通过PostCSS转译实现, PostCSS给一个组件中的所有dom添加了一个独一无二的动态属性,然后,给CSS选择器额外添加一个对应的属性选择器来选择该组件中dom.


<div  adfs-888-123213 ></div>

 

1、内存泄露
内存泄漏指任何对象在您不再拥有或需要它之后仍然存在。 垃圾回收器定期扫描对象,并计算引用了每个对象的其他对象的数量。如果一个对象的引用数量为 0(没有其他对象引用过该对象),或对该对象的惟一引用是循环的,那么该对象的内存即可回收。 1. setTimeout 的第一个参数使用字符串而非函数的话,会引发内存泄漏。 2. 闭包 3. 控制台日志 4. 循环(在两个对象彼此引用且彼此保留时,就会产生一个循环)
2、cookie的弊端
cookie虽然在持久保存客户端数据提供了方便,分担了服务器存储的负担,但还是有很多局限性的。 第一:每个特定的域名下最多生成20个cookie 1.IE6或更低版本最多20个cookie 2.IE7和之后的版本最后可以有50个cookie。 3.Firefox最多50个cookie 4.chrome和Safari没有做硬性限制 IE和Opera 会清理近期最少使用的cookie,Firefox会随机清理cookie。 cookie的最大大约为4096字节,为了兼容性,一般不能超过4095字节。 IE 提供了一种存储可以持久化用户数据,叫做 userData,从IE5.0就开始支持。每个数据最多128K,每个域名下最多1M。这个持久化数据放在缓存中,如果缓存没有清理,那么会一直存在。 优点:极高的扩展性和可用性 1.通过良好的编程,控制保存在cookie中的session对象的大小。 2.通过加密和安全传输技术(SSL),减少cookie被破解的可能性。 3.只在cookie中存放不敏感数据,即使被盗也不会有重大损失。 4.控制cookie的生命期,使之不会永远有效。偷盗者很可能拿到一个过期的cookie。 缺点: 1.`Cookie`数量和长度的限制。每个domain最多只能有20条cookie,每个cookie长度不能超过4KB,否则会被截掉。 2.安全性问题。如果cookie被人拦截了,那人就可以取得所有的session信息。即使加密也与事无补,因为拦截者并不需要知道cookie的意义,他只要原样转发cookie就可以达到目的了。 3.有些状态不可能保存在客户端。例如,为了防止重复提交表单,我们需要在服务器端保存一个计数器。如果我们把这个计数器保存在客户端,那么它起不到任何作用。
3、css盒子模型
①盒模型: 内容(content)、填充(padding)、边界(margin)、 边框(border) ②类型: IE 盒子模型、标准 W3C 盒子模型; ③两种盒模型的主要区别是:标准盒模型的宽高是值内容宽高(content)   ④而IE盒模型的宽高是指content+padding+border。   ⑤设置盒模型的方式是:设置box-sizing     box-sizing:content-box  标准盒模型     box-sizing:border-box IE盒模型   ⑥盒子模型的定位    网页默认的布局方式    浮动    Position定位
4、css3的新特性
1. CSS3实现圆角(border-radius),阴影(box-shadow), 2. 对文字加特效(text-shadow、),线性渐变(gradient),旋转(transform) 3. transform:rotate(9deg) scale(0.85,0.90) translate(0px,-30px) skew(-9deg,0deg);// 旋转,缩放,定位,倾斜 4. 增加了更多的CSS选择器  多背景 rgba 5. 在CSS3中唯一引入的伪类是 ::selection. 6. 媒体查询,多栏布局 7. border-image
5、BFC的理解
BFC,块级格式化上下文,一个创建了新的BFC的盒子是独立布局的,盒子里面的子元素的样式不会影响到外面的元素。在同一个 BFC 中的两个毗邻的块级盒在垂直方向(和布局方向有关系)的 margin 会发生折叠。 W3C CSS 2.1 规范中的一个概念,它决定了元素如何对其内容进行布局,以及与其他元素的关系和相互作用。
6、HTML5的新特性
新特性: HTML5 现在已经不是 SGML 的子集,主要是关于图像,位置,存储,多任务等功能的增加。 1. 拖拽释放(Drag and drop) API  2. 语义化更好的内容标签(header,nav,footer,aside,article,section) 3. 音频、视频API(audio,video) 4. 画布(Canvas) API 5. 地理(Geolocation) API 6. 本地离线存储 localStorage 长期存储数据,浏览器关闭后数据不丢失; 7. sessionStorage 的数据在浏览器关闭后自动删除 8. 表单控件,calendar、date、time、email、url、search   9. 新的技术webworker, websocket, Geolocation 移除的元素: 1. 纯表现的元素:basefont,big,center,font, s,strike,tt,u; 2. 对可用性产生负面影响的元素:frame,frameset,noframes;
7、如何对网站的文件和资源进行优化
1. 文件合并 2. 文件最小化/文件压缩 3. 使用 CDN 托管 4. 缓存的使用(多个域名来提供缓存) 5. 其他
8、减少页面加载时间的方法
1. 优化图片  2. 图像格式的选择(GIF:提供的颜色较少,可用在一些对颜色要求不高的地方)  3. 优化CSS(压缩合并css,如 margin-top, margin-left...)  4. 网址后加斜杠(如www.campr.com/目录,会判断这个目录是什么文件类型,或者是目录。)  5. 标明高度和宽度(如果浏览器没有找到这两个参数,它需要一边下载图片一边计算大小,如果图片很多,浏览器需要不断地调整页面。这不但影响速度,也影响浏览体验。  当浏览器知道了高度和宽度参数后,即使图片暂时无法显示,页面上也会腾出图片的空位,然后继续加载后面的内容。从而加载时间快了,浏览体验也更好了)  6. 减少http请求(合并文件,合并图片)
9、null和undefined的区别
null是一个表示"无"的对象,转为数值时为0 undefined是一个表示"无"的原始值,转为数值时为NaN 当声明的变量还未被初始化时,变量的默认值为undefined null用来表示尚未存在的对象,常用来表示函数企图返回一个不存在的对象 undefined表示 “缺少值”,就是此处应该有一个值,但是还没有定义。典型用法是: 1. 变量被声明了,但没有赋值时,就等于 undefined 2. 调用函数时,应该提供的参数没有提供,该参数等于 undefined 3. 对象没有赋值的属性,该属性的值为 undefined 4. 函数没有返回值时,默认返回 undefined null表示“没有对象”,即该处不应该有值。典型用法是: 1. 作为函数的参数,表示该函数的参数不是对象 2. 作为对象原型链的终点
10、解决跨域问题
1. jsonp(jsonp 的原理是动态插入 script 标签) 2. 服务器上设置代理页面 3. document.domain + iframe 4. window.name、window.postMessage
11、http与https的区别
http传输的数据都是未加密的,也就是明文的,网景公司设置了SSL协议来对http协议传输的数据进行加密处理,简单来说https协议是由http和ssl协议构建的可进行加密传输和身份认证的网络协议 ,比http协议的安全性更高。主要的区别如下: Https协议需要ca证书,费用较高。 http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。 使用不同的链接方式,端口也不同,一般而言,http协议的端口为80,https的端口为443 http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。
12、tcp三次握手
1、客户端向服务器端发送SYN报文seq(x),请求连接,等待服务器端确认 2、服务器端接收到客户端的SYN报文,向客户端发送确认信息 SYN seq(y)+ack(x+1) 3、客户端收到服务器端的报文,向服务器端发送ACK )报文ack=y+1,这个报文段发送完毕以后,客户端和服务器端都进入established状态,完成TCP三次握手。
13、.call()和.apply()的区别
改变this的指向,传参问题,动态改变某个类的某个方法的运行环境
14、内存泄露
内存泄漏指任何对象在您不再拥有或需要它之后仍然存在。 垃圾回收器定期扫描对象,并计算引用了每个对象的其他对象的数量。如果一个对象的引用数量为 0(没有其他对象引用过该对象),或对该对象的惟一引用是循环的,那么该对象的内存即可回收。 1. setTimeout 的第一个参数使用字符串而非函数的话,会引发内存泄漏。 2. 闭包 3. 控制台日志 4. 循环(在两个对象彼此引用且彼此保留时,就会产生一个循环)
15、Node 的优缺点
优点: 1. 因为Node是基于事件驱动和无阻塞的,所以非常适合处理并发请求,因此构建在Node上的代理服务器相比其他技术实现(如Ruby)的服务器表现要好得多。 2. 与Node代理服务器交互的客户端代码是由javascript语言编写的,因此客户端和服务器端都用同一种语言编写,这是非常美妙的事情。 缺点: 1. Node是一个相对新的开源项目,所以不太稳定,它总是一直在变。 2. 缺少足够多的第三方库支持。看起来,就像是Ruby/Rails当年的样子(第三方库现在已经很丰富了,所以这个缺点可以说不存在了)。
16、性能优化
1. 减少http请求次数:CSS Sprites, JS、CSS 源码压缩、图片大小控制合适;网页 Gzip,CDN 托管,data 缓存 ,图片服务器 2. 前端模板 JS + 数据,减少由于HTML标签导致的带宽浪费,前端用变量保存 AJAX 请求结果,每次操作本地变量,不用请求,减少请求次数 3. 用 innerHTML 代替 DOM 操作,减少 DOM 操作次数,优化 javascript 性能 4. 当需要设置的样式很多时设置 className 而不是直接操作 style 5. 少用全局变量、缓存DOM节点查找的结果。减少 IO 读取操作 6. 避免使用 CSS Expression(css表达式)又称 Dynamic properties(动态属性) 7. 图片预加载,将样式表放在顶部,将脚本放在底部,加上时间戳
17、JavaScript继续的6种方法
1. 原型链继承 2. 借用构造函数继承 3. 组合继承(原型+借用构造) 4. 原型式继承 5. 寄生式继承 6. 寄生组合式继承
18、Ajax的过程
1. 原型链继承 2. 借用构造函数继承 3. 组合继承(原型+借用构造) 4. 原型式继承 5. 寄生式继承 6. 寄生组合式继承
19、同源策略
概念: 同源策略是客户端脚本(尤其是Javascript)的重要的安全度量标准。它最早出自Netscape Navigator2.0,其目的是防止某个文档或脚本从多个不同源装载。 这里的同源策略指的是:协议,域名,端口相同,同源策略是一种安全协议,指一段脚本只能读取来自同一来源的窗口和文档的属性。
20、get、post的区别,什么时候用post
GET:一般用于信息获取,使用URL传递参数,对所发送信息的数量也有限制,一般在2000个字符 POST:一般用于修改服务器上的资源,对所发送的信息没有限制 GET方式需要使用 Request.QueryString 来取得变量的值 POST方式通过 Request.Form 来获取变量的值 也就是说 Get 是通过地址栏来传值,而 Post 是通过提交表单来传值。 在以下情况中,请使用 POST 请求: 1. 无法使用缓存文件(更新服务器上的文件或数据库) 2. 向服务器发送大量数据(POST 没有数据量限制) 3. 发送包含未知字符的用户输入时,POST 比 GET 更稳定也更可靠
21、node的适用场景
1. 高并发 2. 聊天 3. 实时消息推送 
22、JavaScript 原型以及原型链,有什么特点
1. 原型对象也是普通的对象,是对象一个自带隐式的 __proto__ 属性,原型也有可能有自己的原型,如果一个原型对象的原型不为 null 的话,我们就称之为原型链 2. 原型链是由一些用来继承和共享属性的对象组成的(有限的)对象链
23、js 浅拷贝和深拷贝
浅拷贝的方法: (1)for···in只循环第一层 (2)Object.assign方法 (3)直接用=赋值 let a=[0,1,2,3,4], b=a; console.log(a===b); a[0]=1; console.log(a,b); 深拷贝的方法: (1)采用递归去拷贝所有层级属性 (2) 通过JSON对象来实现深拷贝 //自带的方法无法拷贝,会undefined (3)通过jQuery的extend方法实现深拷贝 (4)lodash函数库实现深拷贝 (5)Reflect法 (6)手动实现深拷贝 (7)如果对象的value是基本类型的话,也可以用Object.assign来实现深拷贝,但是要把它赋值给一个空对象
 
 
vue
 
1.vue性能优化的几种方案
1.正确的选择v-if和v-show的使用,v-if有更高的切换消耗,v-show有更高的初始消耗 2.路由懒加载:当页面很多,组件很多的时候,SPA页面在首次加载的时候,就会变的很慢。这是因为vue首次加载的时候把可能一开始看不见的组件也一次加载了, 这个时候就需要对页面进行优化,就需要异步组件了。 3.缓存:spa页面采用keep-alive缓存组件 4.图片懒加载:提高页面加载速度,不在可视区域内的图片先不加载,只有滚动到可视区域的时候才加载。一般借助外部插件如 vue-lazyload。 使用只需要npm install vue-lazyload然后页面引入即可使用。 5.SEO优化: ssr服务端渲染 6.打包优化:对于一些过大的包采取cdn引入文件的方式而不是直接下载到本地。
2.v-show和v-if谁的性能更高
v-show本质就是通过控制css中的display设置为none,控制隐藏,只会编译⼀次;v-if是动态的向DOM树内添加或者删除DOM元素,若初始值为false,就不会编译了。 ⽽且v-if不停的销毁和创建⽐较消耗性能。所以如果要频繁切换那么v-show性能更高,如果不是频繁切换,v-if性能更高
 
3.vue之间的数据传递
父到子:props 子到父:$emit自定义事件 复杂组件的传递:通过vuex
 
4.单文件组件中如何让样式只在当前组件生效
在组件中的style前面加上scoped
 
5.vue中的生命周期(钩子函数)
共有8+2个钩子函数 基本的有8个,keep-alive中有2个 beforeCreate(创建前) / created(创建后) / beforeMount(挂载前) / mounted(挂载后) beforeUpdate(更新前)/ updated(更新后) /beforeDestroy(销毁前)/ destroyed(销毁后) 其中第一次加载页面会触发 beforeCreate, created, beforeMount, mounted 这几个钩子 另外在keep-alive中,vue新增了两个钩子函数 activated:因为使用了keep-alive的组件会被缓存,所以created,mounted这种的钩子函数只会执行一次, 如果我们的子组件需要在每次加载的时候进行某些操作,可以使用activated钩子触发。 deactivated:组件被移除时使用。
 
6.vue父子组件生命周期的执行顺序
加载渲染过程 父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted 子组件更新过程 父beforeUpdate->子beforeUpdate->子updated->父updated 父组件更新过程 父beforeUpdate->父updated 销毁过程 父beforeDestroy->子beforeDestroy->子destroyed->父destroyed
 
7.在vue中如何获取DOM元素
给元素添加ref属性 通过this.$refs.domName获取
 
8.key的作用
需要使用key来给每个节点做一个唯一标识,Diff算法就可以正确的识别此节点。 作用主要是为了高效的更新虚拟DOM。
 
9.$nextTick的使用场景(作用)
因为vue中数据更新是异步的,当你修改了data的值然后马上获取这个dom元素的值,是不能获取到更新后的值, 你需要使用$nextTick这个回调,让修改后的data值渲染更新到dom元素之后在获取,才能成功。
 
10.v-if和v-for的优先级
v-if 与 v-for 一起使用时,v-for 具有比 v-if 更高的优先级,这意味着 v-if 将分别重复运行于每个 v-for 循环中。所以,不推荐v-if和v-for同时使用。如果非要一起用,可以把v-if放到外层元素,或者不用v-if,先在计算属性中筛选出数据,然后在v-for
 
11.v-model的原理
vue 双向数据绑定是通过 数据劫持 结合 发布订阅模式的方式来实现的, 也就是说数据和视图同步,数据发生变化,视图跟着变化,视图变化,数据也随之发生改变; 核心:关于VUE双向数据绑定,其核心是 Object.defineProperty()方法。
 
12.什么是mvvm
MVVM 将数据双向绑定(data-binding)作为核心思想,View 和 Model 之间没有联系,它们通过 ViewModel 这个桥梁进行交互。 Model 和 ViewModel 之间的交互是双向的,因此 View 的变化会自动同步到 Model,而 Model 变化也会立即反映到 View 上显示。 当用户操作 View,ViewModel 感知到变化,然后通知 Model 发生相应改变;反之当 Model 发生改变,ViewModel 也能感知到变化,使 View 作出相应更新。
 
13.如何优化SPA应用的首屏加载速度慢的问题
将公用的JS库通过script标签外部引入,减小app.bundel的大小,让浏览器并行下载资源文件,提高下载速度; 在配置 路由时,页面和组件使用懒加载的方式引入,进一步缩小 app.bundel 的体积,在调用某个组件时再加载对应的js文件; 加一个首屏 loading 图,提升用户体验;
 
14.vue路由的两种模式,hash与history的区别
hash —— 即地址栏 URL 中的 # 符号(此 hash 不是密码学里的散列运算)。 比如这个 URL:ABC Home Page - ABC.com 的值为 #/hello。它的特点在于:hash 虽然出现在 URL 中,但不会被包括在 HTTP 请求中,对后端完全没有影响,因此改变 hash 不会重新加载页面。 history —— 利用了 HTML5 History Interface 中新增的 pushState() 和 replaceState() 方法。(需要特定浏览器支持) 这两个方法应用于浏览器的历史记录栈,在当前已有的 back、forward、go 的基础之上,它们提供了对历史记录进行修改的 功能。只是当它们执行修改时,虽然改变了当前的 URL, 但浏览器不会立即向后端发送请求。 因此可以说,hash 模式和 history 模式都属于浏览器自身的特性,Vue-Router 只是利用了这两个特性(通过调用浏览器提供 的接口)来实现前端路由。 注意!!!history模式下,前端的url必须和实际向后端发起请求的url 一致,如http://www.abc.com/book/id 。如果后端缺少对/book/id 的路由处理,将返回404错误。 刷新也会报404因为会实际去请求数据。 (需要后端进行配置。vue官网有介绍)
 
15.如何解决vuex数据刷新丢失的问题
因为store里的数据是保存在运行内存中的,当页面刷新时,页面会重新加载vue实例,store里面的数据就会被重新赋值 如何解决: 一种是state里的数据全部是通过请求来触发action或mutation来改变(不推荐,当vuex数据很多项目很大的时候不适用) 一种是将state里的数据保存一份到本地存储(localStorage、sessionStorage、cookie)中 (推荐)
 
16.vue中如何实现跨域访问
1.开发环境:配置vue.config.js proxy代理 2.生产环境:配置nginx代理
 
 
1.vue的原理?
0
 
关键词: 虚拟DOM树+访问器属性
  • 解释一下:响应式原理?
当你把一个普通的 JavaScript 对象传入 Vue 实例作为 data 选项,Vue 将遍历此对象所有的 property,并使用 Object.defineProperty把这些 property 全部转为 getter/setter这些 getter/setter 对用户来说是不可见的,但是在内部它们让 Vue 能够追踪依赖,在 property 被访问和修改时通知变更,每个组件实例都对应一个 watcher 实例,它会在组件渲染的过程中把“接触”过的数据 property 记录为依赖。之后当依赖项的 setter 触发时,会通知 watcher,从而使它关联的组件重新渲染。
 
  • vue为什么不支持IE8及更低版本?
Object.defineProperty` 是 ES5 中一个无法 shim 的特性,这也就是 Vue 不支持 IE8 以及更低版本浏览器的原因。
 
2. vue有哪些缺点
Vue 不能检测数组和对象的变化
 
3.为什么vue不能检测对象的变化
对于对象, Vue 无法检测 property 的添加或移除,由于 Vue 会在初始化实例时对 property 执行 getter/setter 转化,所以 property 必须在 data 对象上存在才能让 Vue 将它转换为响应式的.
 
  • 追问:那如何解决上述问题?
使用this.$set(this.someObject,'b',2) 添加新的属性 使用this.$delete(this.someObject,'b') 删除旧属性
 
4.讲一下 $set 的实现原理
1、如果目标是数组,使用 vue 实现的变异方法 splice 实现响应式 2、如果目标是对象,判断属性存在,即为响应式,直接赋值 3、如果 target 本身就不是响应式,直接赋值 4、如果属性不是响应式,则调用 defineReactive 方法进行响应式处理
 
核心代码如下
 
export function set(target: Array | Object, key: any, val: any): any { // target 为数组 if (Array.isArray(target) && isValidArrayIndex(key)) { // 修改数组的长度, 避免索引>数组长度导致splice()执行有误 target.length = Math.max(target.length, key); // 利用数组的splice变异方法触发响应式 target.splice(key, 1, val); return val; } // target为对象, key在target或者target.prototype上 且必须不能在 Object.prototype 上,直接赋值 if (key in target && !(key in Object.prototype)) { target[key] = val; return val; } // 以上都不成立, 即开始给target创建一个全新的属性 // 获取Observer实例 const ob = (target: any).__ob__; // target 本身就不是响应式数据, 直接赋值 if (!ob) { target[key] = val; return val; } // 进行响应式处理 defineReactive(ob.value, key, val); ob.dep.notify(); return val; }
 
5.new Vue()实例中,data 可以直接是一个对象,为什么在 vue 组件中,data 必须是一个函数呢?
关键词:复用+污染 + 函数返回 + 数据拷贝
因为组件是可以复用的,JS 里对象是引用关系,如果组件 data 是一个对象,那么子组件中的 data 属性值会互相污染,产生副作用。所以一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝。new Vue 的实例是不会被复用的,因此不存在以上问题。
 
6.computed 和 watch 有什么区别?
0
 
computed 计算属性 : 依赖其它属性值,只有它依赖的属性值发生改变,下一次获取 computed 的值时才会重新计算 computed 的值,如果和上次计算结果不一致,重新渲染页面。 watch 侦听器 : 更多的是「观察」的作用,无缓存性,类似于某些数据的监听回调,每当监听的数据变化时都会执行回调进行后续操作。
 
追问:computed 和 watch 应用场景? 关键词 computed+缓存
computed :当我们需要进行数值计算,并且依赖于其它数据时,应该使用 computed,因为可以利用 computed 的缓存特性,避免每次获取值时,都要重新计算。 watch: 当我们需要在数据变化时执行的操作时使用(如调用其它函数)
 
追问 :能使用箭头函数定义computed和watch吗?
不应该使用箭头函数来定义 watcher 函数,理由是箭头函数绑定了父级作用域的上下文,所以 this 将不会按照期望指向 Vue 实例,为undefined
 
7.MVC和MVVM的原理
MVC
 
0
 
视图(View):用户界面。 控制器(Controller):业务逻辑 模型(Model):数据保存
 
实现流程
1.View 传送指令到 Controller 2.Controller 完成业务逻辑后,要求 Model 改变状态 3.Model 将新的数据发送到 View,用户得到反馈
 
  • MVVM
视图(View):用户界面。 视图模型(VM):双向数据绑定 模型(Model):数据+业务
 
在MVVM架构下,View 和 Model 之间并没有直接的联系,而是通过ViewModel进行交互. Model 和 ViewModel 之间的交互是双向的, 因此View 数据的变化会同步到Model中,而Model 数据的变化也会立即反应到View 上。
 
0
 
 
 
8.vue数据绑定是双向还是单向的
Vue 在不同组件间强制使用单向数据流。这使应用中的数据流更加清晰易懂。
 
9.v-model双向绑定的原理?
v-model 本质上不过是语法糖。它负责监听用户的输入事件以更新数据.
 
原理如下:
Object.defineproperty()重新定义(set方法)对象设置属性值和(get方法)获取属性值的操纵来实现的. 1.实现一个监听器Observer,用来劫持并监听所有属性,如果有变动的,就通知订阅者。 2.实现一个订阅者Watcher,可以收到属性的变化通知并执行相应的函数,从而更新视图。 3.实现一个解析器Compile,可以扫描和解析每个节点的相关指令,并根据初始化模板数据以及初始化相应的订阅器。
 
9.全局导航钩子函数应用场景?
vue router.beforeEach(全局前置守卫)router.beforeEach 是页面加载之前(before each)意思是在 每次每一个路由改变的时候都得执行一遍. vue router.afterEach(全局后置守卫),相反router.afterEach是页面加载之后.
 
应用场景:
可进行一些页面跳转前处理,例如判断需要登录的页面进行拦截,做登录跳转! 2.进入页面登录判断、管理员权限判断、浏览器判断
 
10 .v-if和v-for在同一个标签中的执行顺序?
v-for 比 v-if 优先级高,如果每一次都需要遍历整个数组,将会影响速度注意v-for 遍历避免同时使用 v-if
 
如果需要使用判断,建议使用计算属性
 
<ul> <li v-for="user in activeUsers" :key="user.id"> {{ user.name }} </li></ul> computed: { activeUsers: function () { return this.users.filter(function (user) { return user.isActive }) }}
 
10.路由独享的守卫(路由内钩子)
路由独享的守卫(路由内钩子)你可以在路由配置上直接定义 beforeEnter 守卫:
 
const router = new VueRouter({ routes: [ { path: '/foo', component: Foo, beforeEnter: (to, from, next) => { // 处理 ... next() } } ]
 
11.vue-loader是什么?它有什么作用?
 
解析和转换 .vue 文件,提取出其中的逻辑代码 script、样式代 码 style、以及 HTML 模版 template,再分别把它们交给对应的 Loader 去处理。
 
12.vue中怎么重置data?
 
this .$options.data可以获取到组件初始化状态下的datathis.$data获取当前状态下的data// 将数据拷贝到this.$data中即可Object.assign(this.$data, this.$options.data())
 
13.在vue项目中如果methods的方法用箭头函数定义结果会怎么样?
因为箭头函数默绑定父级作用域的上下文,所以不会绑定vue实例, 在严格模式下this是undefined,在非严格模式下指向window
 
14.vue怎么实现强制刷新组件?
1.调用强制刷新方法 this.$forceUpdate()
 
  1. 给模板上绑定key值,通过修改key值,实现组件刷新//选项里绑定datadata(){ return{ theKey:0 }}//刷新key达到刷新组件的目的theKey++;
15.如何在子组件中访问父组件的实例?
通过this.parent.event来调用父组件的方法 2:在子组件里用$emit向父组件触发一个事件,父组件监听这个事件
 
3:父组件把方法传入子组件中,在子组件里直接调用这个方法父组件如何调用子组件的方法?给子组件设置属性ref <子组件 ref="name" />可以在子组件中加上ref,然后通过this.$refs.ref.method调用
16.vue组件里写的原生addEventListeners监听事件,要手动去销毁吗?为什么?
需要, Vue不会主动移除监听事件, 多次进入组件,事件会绑定多次,另一方面是函数没释放会内存溢出.
 
17.组件中写name选项有什么作用?
a.项目使用keep-alive时,可搭配组件name进行缓存过滤b.DOM做递归组件时需要调用自身name c.vue-devtools调试工具里显示的组见名称是由vue中组件name决定的
 
18.有什么用?
当做一个不可见的包裹元素,减少不必要的DOM元素,整个结构会更加清晰。使用场景主要用于分组的条件判断和列表渲染。结合v-for、v-if等一起使用,插槽时使用
 
19 .vue组件之间的通信都有哪些?
父子组件传值
 
  1. 通过props属性传值
  2. 通过
  3. on传值
  4. (
  5. children ) / $refs
兄弟组件传值 1.Vuex 2.Bus 跨级组件传值
 
  1. provide/inject
  2. listeners
20.route和router有什么区别?
route:代表当前路由信息对象,可以获取到当前路由的信息参数router:代表路由实例的对象,包含了路由的跳转方法,钩子函数等
 
21.怎样动态加载路由?
通过router.addRoutes方法可以动态加载路由.
 
 
let router=new VueRouter({ routes:[ {path:'/product',component:a,name:'product'} ] }); router.addRoutes([ {path:'/user',component:c,name:'user'}, {path:'/address',component:address,name:'address'} ]);
 
22.说说active-class是哪个组件的属性?
active-class是vue-router模块的router-link组件中的属性,用来设置选中连接的样式.
 
23.为什么vue使用异步更新组件?
收集当前的改动一次性批量更新,为了节省diff开销.
 
24.怎么缓存当前的组件?缓存后怎么更新?
 
 
1.通过keep-alive组件缓存需要缓存的组件
 
<keep-alive includes="组件1name,组件2name"> <router-view> </keep-alive>
 
2.当组件激活后,会触发钩子函数actived,在这个钩子函数中,做数据更新.
25.vue怎么获取DOM节点?
为组件定义ref属性通过this.$refs.myInput 就可以获取dom节点.
 
26.vuex中actions和mutations有什么区别?
1.mutations可以直接修改state,但只能包含同步操作,同时,只能通过提交commit调用. 2.actions可以包含异步操作,通过store.dispatch触发,不能直接修改数据,需要调用commit去修改数据.
 
27. 怎么监听vuex数据的变化?
通过watch监听数据的变化
 
 
watch:{ '$store.state.test':function(value){ console.log('数据修改了',value) }}
 
28.开启vuex中的严格模式有什么好处?
主要用户防止不合理的改变状态值如:this.$.store.state.list = [],这样就会抛出异常
 
A.在严格模式下,无论何时发生了状态变更且不是由 mutation 函数引起的,将会抛出错误。这能保证所有的状态变更都能被调试工具跟踪到。 B. 不要在发布环境下启用严格模式!严格模式会深度监测状态树来检测不合规的状态变更——请确保在发布环境下关闭严格模式,以避免性能损失。
如何使用?
 
const store = new Vuex.Store({ // 让构建工具自动帮我们处理 strict: process.env.NODE_ENV !== 'production' })
 
30.你了解双向绑定的计算属性的应用场景吗?
 
<input type="text" v-model="username">
 
如果我们想要监听用户输入变化,我们首先会想到下面的方法
 
<input type="text" v-model="username" @input="onChange">
 
其实我们可以使用双向绑定的计算属性来实现
 
data() { return { _username:'' }; }, computed:{ username:{ get(){ return this._username }, set(value){ // 监听数据变化 console.log('监听数据变化',value) this._username = value } } }
 
当我们使用了Vuex时,并且开启了严格模式,那么我们就不能直接绑定状态值了, 在用户输入时,v-model 会试图直接修改状态name的值,这样会抛出异常这个时候我们需要使用双向绑定的计算属性来解决这个问题
 
<input v-model="name"> computed: { name: { get () { return this.$store.state.name }, set (value) { this.$store.commit('updateName', value) } }}
 
30.vue中的指令v-on如何绑定多个属性?
v-on={ 事件名:绑定的自定义回调函数}
 
 
<input type="text" v-on="{input:onInput,focus:onFocus}"/>
 
31.vue中使用delete删除对象的属性,页面会更新吗?
delete this.list[1] 页面不会更新, Vue不能检测到 property 被删除那么如何在删除元素或者对象属性时,可以触发更新视图? this.$delete(this.list,1)
 
32.watch怎么深度监听对象变化?
 
data() { return { data:{}, user:{ info:{ name:123 } } }; }
 
比如我们要对user.info 属性进行监听,如果info属性有任何更改触发通知
 
watch:{ 'user.info':{ handler(value){ console.log("数据变化",value) } } }
 
此时我们调用
this.user.info.name = "8888888"handle方法不会被触发.这个user.info是一个对象 Vue只响应对象的地址变化进行响应. 如果我们需要让Vue对整个info里面的属性变化,进行监听, 就需要开启深度监听属性deep:true
 
watch:{ 'user.info':{ handler(value){ console.log("数据变化",value) }, deep:true } }
 
33 .vue组件会在什么时候下被销毁?
1.页面关闭、 2.路由跳转、 3.v-if为false 4.改变key值
 
33.怎么使css样式只在当前组件中生效
给style标签添加scoped属性, 通过该属性,可以使得组件之间的样式不互相污染
 
原理vue中的scoped属性的效果主要通过PostCSS转译实现, PostCSS给一个组件中的所有dom添加了一个独一无二的动态属性,然后,给CSS选择器额外添加一个对应的属性选择器来选择该组件中dom.
 
<div adfs-888-123213 ></div>
 
 
 
 
 
 
 
 
posted @ 2022-06-27 11:25  小旺同学  阅读(303)  评论(2编辑  收藏  举报