面试题记录

301 阅读32分钟

一 css问题

1.flex布局

display:flex;在父元素设置,子元素受弹性盒子影响,默认拍成一行,如果超出一行,按比例压缩 flex:1;子元素设置,设置子元素如何分配父元素的空间,flex:1;子元素宽度沾满整个父元素 align-items 定义子元素在父容器中的对齐方式,center垂直居中 justify-content 设置子元素在父元素中水平居中,前提是子元素没有把父元素占满,让子元素水平居中

2.css的新特性

transition transition-property 规定设置过渡效果的css属性的名称 transition-duration 过渡效果需要多少毫秒 transition-timing-function 规定速度效果的速度曲线 transition-delay 过渡效果何时开始 animation 动画效果 控制关键帧来控制动画的每一步,实现复杂的动画效果

3.img中alt和title的区别

alt:图片上的alt属性是在图片不能正常显式时出现的文本提示,alt有利于seo优化 title:图片中title属性是鼠标在移动到元素上的文本提示

4.用纯css创建一个三角形

<style>
  div{
    width:0;
    height:0;
    border-top:40px solid transparent;
    border-left:40px solid transparent;
    border-right:40px solid transparent;
    border-bottom:40px solid #ff0000;
  }
</style>
<body>
    <div></div>
</body>

图片.png

5.如何理解css的盒模型

图片.png 可以看到,在标准盒模型下,width 和 height的区域即content的width和height,在标准模式下,一个块的总宽度=width + margin(左右) + padding(左右) + border(左右)

图片.png IE 盒模型或者说是 怪异盒模型 显而易见的区别就是,width 和 height除了content 区域外,还包含padding和border, 一个块的总宽度 = width + margin(左右)(即width已经包含了padding和border的值)

1.如何运用

只要在文档首部加了doctype声明,即使用了标准盒模型,不加则会由浏览器自己决定

2.怪异盒模型

css3的的box-sizing

当设置为 content-box的时候,采用标准模式解析

当设置为 border-box的时候,采用怪异模式解析

6.如何让一个div水平居中

margin:0 auto;

绝对定位的居中,transition:absolute;left:50%;transform:translateX(-50%);

flex 的 justify-content:center;

position:absolute ; width:固定; left:50%; margin-left: -0.5宽度;

7.如何让一个div水平垂直居中

flex display:flex; align-items:center;

绝对定位 position:absolute; top:50%; translateY(-50%)

元素高度固定:position:absolute;top:50%;height:固定;margin-top:-0.5高度;

8.如何清除浮动

clear清除浮动 在浮动元素下方添加空div,并给该元素写css样式 {clear:both;height:0;overflow:hidden;}

给浮动元素的父级设置高度

父级同时浮动

父级设置 overflow:hidden;

万能清除法 after伪类实现清除浮动 主推

.clearfix:after{
   content:'';
   clear:both;
   display:block;
   height:0;
   overflow:hidden;
   visibility:hidden;
}
.clearfix{
   zoom:1;
}

9.实现三栏布局,左右固定,中间自适应

双飞翼布局

<style>
*{
margin:0;
padding:0;
}
#container{
width:100%;
height:500px;
}
#left,#center,#right{
float:left;
}
#center{
 width:100%;
 height:500px;
 background-color:red;
}
#left{
width:200px;
height:500px;
background-color:green;
margin-left:-100%;
}
#right{
width:150px;
height:500px;
background-color:pink;
margin-left:-150px;
}
#center-box{
  margin:0 150px 0 200px;
  background-color:orange;
}

</style>
<body>
  <div id="container">
    <div id="center">
      <div id="center-box">
      </div>>
    </div>
    <div id="left"></div>
    <div id="right"></div>
  </div>
</body>

10.display:none 和 visibility:hidden 和 opacity的区别

  1.是否占据空间
  display:不占据空间
  visibility:占据空间
  opacity:占据空间
  2.子元素是否继承
  display: 不会被子元素继承,父元素都不存在,子元素也不会显示出来
  visibility:会被子元素继承,通过设置子元素 visibility:visible来显示子元素
  opacity:会被子元素继承,但是不能通过设置display让子元素重新显示
  3.事件绑定
  display: 元素都不在页面存在,自然无法触发其事件
  visibility: 不会触发它上面的事件
  opacity  元素上绑定的事件会触发的
  4.动画过渡
  transition   对display和visibility无效,对opacity有效

11.css中link和@import的区别是

link属于HTML标签,而@import是css提供的 页面被加载时,link会同时被加载,而@import引用的css会等到页面都被加载完再加载

import 只在ie5以上才识别,而link是HTML标签,无兼容问题

link方式的样式的权重高于@import的权重

12.position的absolute与fixed共同点与不同点

共同点:改变元素的呈现方式,让元素脱标,不占据空间

不同点:absolute的根元素是可以设置的,fixed的根元素固定为浏览器。当你滚动网页,flex元素与浏览器窗口之间的距离是不变的

13.transition 和 animation 的区别

animation和transition 大部分属性是相同的,都是随着时间改变元素的属性值,主要的区别是transition需要触发一个事件才能改变属性,而animation不需要触发任何事件,并且transition为2帧,从from---to,而animation可以一帧一帧de

transition规定动画的名字,过渡效果需要多少秒 规定速度,定义何时开始 animation要绑定到选择器的关键帧的名称

14.css优先级

不同级别:总结排序: !important >行内样式>id选择器>类选择器>标签>通配符>继承>浏览器默认属性
1.属性后面加上 !important 会覆盖页面内任何位置定义的元素样式
2.作为style属性写在元素内的样式
3.id选择器
4.class选择器
5.标签选择器
6.通配符选择器
7.继承的样式
8.浏览器默认的样式

css选择器的解析原则:选择器定位dom元素从右往左的方向,这样尽可能早的过滤掉一些不必要的样式规则和元素

15.雪碧图

  多个图片集成在一个图片中的图
  使用雪碧图可以减少网络请求的次数,加快运行的速度
  通过background-position 去定位图片在屏幕的哪个位置

16.让元素消失的方法

visibility:hidden; display:none; z-index:-1; opacity:0
1.opacity:0 该元素隐藏起来了,但是不会改变页面布局,并且如果该元素已经绑定了事件,如click等,也能触发
2.visibility:hideen;该元素隐藏起来了,不会改变页面布局,也不会触发该元素绑定的事件了
3.display:none;把元素隐藏起来了,并且会改变页面布局

js问题

1.typeof和instance of检测数据类型有什么区别

相同点:都是用来判断一个变量是否为空,或者是什么类型的

不同点:typeof返回一个字符串,用来说明变量的数据类型 instance of 用于判断一个变量是否属于某个对象的实例

2.谈一谈深克隆和浅克隆

浅克隆:只是拷贝了基本类型的数据,而引用类型数据,复制后也会发生引用,这种拷贝叫浅拷贝,浅拷贝仅仅是指向被复制的内存地址,如果源地址中的对象改变了,那么浅拷贝出来的对象也会相应改变

深拷贝 :创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。JSON.parse() JSON.stringify()

3.es6新特性

let定义块级作用域变量,没有变量的提升,必须先声明后使用,不能与前面let,var,const声明的变量重名,不能重新赋值

const 定义只读变量 const声明变量的同时必须赋值,const声明的变量必须初始化,一旦初始化完毕就不允许修改,也是块级作用域,没有变量提升,必须先声明后使用,变量名不许重名,如果定义的是数组,对象,则属性值可以修改,是基础数据类型不可以修改

es6 可以形参函数设置默认值

在数组之前加上 ... 展开运算符

数据的解构赋值,对象的解构赋值

箭头函数的特点:箭头函数相当于匿名函数,是不能作为构造函数的,不能被new 箭头函数没有arguments实参集合,取而代之的是用reset参数代替(..args) 箭头函数内部的this就是定义时上层作用域中的this,也就是说箭头函数的this是固定的,不能使用call,apply,bind改变箭头函数中的this指向

4. == 和 ===的区别是什么

= 赋值

== 返回一个布尔值,相等是true,不等是false,允许不同数据类型之间的比较,会默认的解析数据类型转换,如果是对象数据类型的比较,比较的是空间地址

=== 是要数据类型不一样,就返回false

5.常见的设计模式有哪些

6.call bind apply的区别

call()和apply()的第一个参数相同,就是指定的对象。该对象就是该函数的执行上下文

call()和apply()的区别在于,两者之间的参数

call()在第一个参数之后的,后续所有的参数就是传入该函数的值,一参数列表

apply()只有两个参数,第一个是对象,第二个是数组,这个数组就是该函数的参数,bind()方法和前两者不同在于:bind()方法会返回执行上下文被改变的函数而不会立即执行,而前两者都是直接执行该函数,参数和call()相同

7.js继承方式有哪些

原型链继承:将父类的实例作为子类的原型

借用构造函数继承:使用父类的构造函数来增强子类实例,等于是复制父类的实例属性给子类

实例继承: 为父类实例添加新特性,作为子类实例返回

拷贝继承

组合继承:通过调用父类的构造函数,继承父类的属性并保留其传参的优点,然后将父类实例作为子类原型,实现函数复用

寄生组合继承:通过寄生的方式,砍掉父类的实例属性,这样在调用两次父类的构造的时候,就不会初始化两次实例方法、属性,避免了组合继承的缺点

8.怎么看待闭包

闭包是指有权访问另一个函数作用域中变量的函数。内部的函数存在外部作用域的引用就会导致闭包。可以保护函数的私有变量不受外部的干扰,形成不销毁的栈内存。保存,把一些函数内的值保存下来,闭包可以实现方法和属性的私有化。

9.原型和原型链

把所有对象共用的属性全部放到一个堆内存的对象中(共用属性组成的对象),然后让每一个对象的__proto__ 存储这个对象地址。而这个公共属性就是原型,原型出现的目的就是减少不必要的内存消耗,而原型链就是对象通过__proto__向当前实例所属类的原型上查找属性和方法的机制,如果找到object的原型上还是没有找到要找的属性或者方法则结束,最终会返回undefined

10.浏览器渲染的主要流程

将html代码按照深度优先遍历来生成DOM树,css文件下载完之后也会进行渲染,生成相应的cssom,当所有的css文件下载完并且cssom构建完毕,就会和dom一起生成render tree。接下来浏览器就会进入layout环节将所有的节点位置计算出来,最后通过painting环节将左右的节点内容呈现在屏幕上

11.从输入url地址到页面响应都发生了什么

1.浏览器的地址栏输入url地址,并点击回车

2.浏览器查找当前url是否存在缓存,并比较缓存是否过期

3.dns解析url对应的ip地址

4.根据ip地址建立tcp连接

5.发起http请求

6.服务器处理请求,浏览器接收到响应

7.渲染页面,构建dom树

8.关闭tcp连接

12.session,cookie,localStorage的区别

相同点:都是保存在浏览器端,且同源的

不同点:

  1. cookie数据始终在同源的http请求中携带,即cookie在浏览器和服务器间来回传递
  2. sessionStorage 和 localStorage 不会自动把数据发给服务器,仅在本地保存
  3. cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下。存储大小限制也不同,cookie数据不能超过4k , 同时因为每次http请求都会携带cookie,所以cookie只适合保存很小的数据
  4. sessionStorage 和 localStorage 虽然也有存储大小的限制,但是比cookie大得多,可以达到5m或更大。数据有效期不同,sessionStorage 仅在当前浏览器窗口关闭前有效,自然也就不可能持久保持
  5. localStorage 始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据
  6. cookie只在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭。作用域不同 sessionStorage 不在不同的浏览器窗口中共享,即使是同一个页面
  7. localStorage 在所有同源窗口中都是共享的,cookie也是在所有同源窗口中都是共享的

13.js中跨域方法

同源策略(协议+端口号+域名都要相同)

jsonp跨域(只能解决get)原理:动态创建一个script标签,利用script标签的src属性不受同源策略的限制,因为所有的src属性和href属性都不受同源策略的限制,可以请求第三方服务器资源内容

 步骤:去创建一个script标签,给script标签的src属性设置接口地址,必须要带一个自定义函数名,通过自定义函数名去接收返回的数据

CORS 服务器设置CORS: Access-Control-Allow-Origin 响应头之后,浏览器将会允许跨域请求

14.前端有哪些页面优化的方法

减少http的请求,配置http缓存

资源合并和压缩 图片,css,js

将外部脚本置底

多图片使用懒加载

尽量少的使用闭包,嵌套循环和死循环,减少dom的操作

用字体图标和svg图标来代替传统的图片图标

尽可能使用事件委托来处理事件绑定

15.Ajax的四个步骤

1.创建ajax实例

2.确认open的地址,是否有参数,同步还是异步

3.监听请求状态

4.发送请求

16.数组的去重

es6的Set对象

const arr = [1,2,3,4,3,3,3]
const result = [...new Set(arr)]

es5 的方法

//1.数组数据的比较
function unique(arr){
  const arr2 = arr.sort()
  const res = [arr2[0]]
  for(let i=1 ; i<arr2.length ; i++){
    if(arr2[i] !== res[res.length-1]){
      res.push(arr2[i])
    }
  }
  return res
}
//2.利用indexOf来查找
function unique(arr){
  const newArray = [arr[0]]
  for(let i=1 ; i<arr.length ; i++){
    if(newArray.indexOf(arr[i]) == -1){
      newArray.push(arr[i])
    }
  }
  return newArray
}

17.ajax中get和post请求的区别

get: get请求一般用于获取数据。 get请求如果需要传递参数,会默认将参数拼接到url的后面,然后发送给服务器。 get请求传递参数大小是有限制的,即浏览器地址栏的大小限制。 get安全性低 。 get一般会走缓存,为了防止走缓存,可以给url后面每次拼接的参数不同,可以用个时间戳

post: post请求一般用于发送数据。post请求传递参数,需要把参数放到请求体中,发送给服务器。 对大小没要求 。 安全性比较高 。 post请求不会走缓存

18. ajax状态码

2开头 比如 200 代表请求成功

3 开头 301 永久重定向 302临时转移 304读取缓存 307 临时重定向

4 开头 的都是客户端的问题 400 数据/格式错误 401 权限不够 (身份不合格,访问网站的时候登陆和不登陆是不一样的) 404 路径错误 找不到文件

5 开头 服务端的问题 500 服务器问题 503 超负荷

19.移动端的兼容问题

  1. 给移动端添加点击事件会有300ms的延迟,如果用点击事件,需要引入一个fastclick.js文件,解决300ms的延迟,一般在移动端使用ontouchstart ontouchmove ontouchend
  2. 移动端点透问题,touchstart早于touchend 早于 click, click的触发是有延迟的,这个时间大概300ms,也就是说我们tap触发之后,蒙层隐藏,此时click还没有触发,300ms以后由于蒙层隐藏,我们的click触发到了下面的a链节上 , 尽量使用touch事件来替换click事件
  3. 设置缓存手机页面通常在第一次加载后会进行缓存,然后每次刷新都会使用缓存而不是重新向服务器发送请求,如果不希望使用缓存可以设置 no-cache
  4. 圆角bug 某些安卓手机圆角失效 background-clip:padding-box ; 防止手机中网页的放大和缩小 5.设置用户截止缩放,一般写视口的时候就已经写好了

20 js中同步和异步,以及js事件流

同步:在同一时间只做一件事 异步:在同一时间做多个事,js是单线程的,每次只能做一件事,js运行在浏览器中,浏览器是多线程的,可以在同一时间执行多个任务

21 js中常见的异步任务

回调函数,定时器,ajax,事件绑定 , async await , promise readFile

22. 三次握手和四次挥手

三次握手

  1. 客户端生成一个随机初始化序号,向服务端发送SYN ,要求建立数据连接
  2. 服务端也生成一个随机初始化序号,然后还生成一个ack,都发送给客户端,表示可以建立连接 3.客户端发起ack响应报文给服务端,服务端验证ack没问题,建立连接成功

四次挥手

  1. 客户端发送FIN报文,通知服务器要关闭连接
  2. 服务器接收到以后,先发送ack报文给客户端,表示已经接收到了消息,但是数据还没传完
  3. 服务端等数据传完,再发送FIN报文给客户端,表示数据传输完毕
  4. 客户端发起ack报文,表示已经知晓,这样两边都可以关闭连接了 但是客户端会等2MSL 就是报文传输的最大声生命周期(2) 然后如果没收到服务端的报文,就会关闭连接了

23. 为什么建立连接时三次握手,而断开连接是四次挥手

因为ACK和FIN 一般都会分开发放,从而导致多了一次

24 dom dff原理

对比(diff)渲染更新前后产生的虚拟dom对象的差异化,并产出差异补丁对象,再将差异补丁对象应用到真实的dom节点上

对比的原理:

  1. 元素类型发生变化,直接替换
  2. 如果是文本,则比较文本里面的内容,如果是元素就比较当前元素的属性

25.作用域

1.全局作用域

浏览器打开页面时,浏览器会给js代码一个全局的运行环境,这个环境就是全局作用域 , 一个页面就一个全局作用域。全局作用域下有一个window对象 window 是全局作用域下的最大的内置对象,在私有作用域中能获取到全局变量,但是在全局作用域中不能获取私有变量

2.私有作用域

函数执行会形成一个新的私有的作用域(执行多次,形成多个私有作用域)私有作用域在全局作用域中形成,具有包含关系;在一个全局作用域中,可以有很多个私有作用域,在私有作用域下定义的变量都是私有变量,形参也是私有变量,函数体中通过function定义的函数也是私有的,全局作用域不能使用

3.块级作用域

es6新引入的一种作用域,在js中常见到 if{} , for{} ,while{} , try{} , catch{} , switch{}等都是块级作用域 var obj = {} 对象的大括号不是块级作用域,块级作用域中的同一变量不能重复声明

  1. 上级作用域

函数在哪里定义的,他的上一级作用域就是哪,和函数在那个作用域下执行没有关系

域链:当获取变量对应的值的时候,首先看变量是否是私有变量,如果不是私有变量要到上级作用域中去找,如果上级也没有,就继续往上一级查找,直到找到为止,如果找到全局作用域还是没有,就会报错

26 Promise处理异步

promise是es6中新增的一个类(new Promise) , 目的是为了管理js中的异步编程,所以把它称之为 promise设计模式 new Promise经历三个状态 padding(准备状态:初始化成功,开始执行异步的任务) fullfilled(成功状态) rejected(失败状态) ; promise本身是同步编程,但是可以管理异步操作 , new Promise 的时候,会把传递的函数立即执行 promise有两个参数 resolve(异步执行成功执行) 和 reject(异步操作执行失败执行) then方法中有两个函数,第一个传递的函数是resolve,第二个传递的函数是reject

27 map和forEach的区别

相同点: 都是循环遍历数组中的每一项,都支持三个参数 item , index , 和arr(原数组),需要用哪个的时候写哪个 匿名函数的this都是指向window,都只能遍历数组

不同点:map 方法返回一个新的数组,数组中的元素为原始数组调用函数处理后的值,map方法不会改变原数组,map方法不会对空数组进行检测 ,forEach方法用于调用数组的每个元素,将元素传给回调函数(没有return,返回值是undefined)

forEach对空数组不会调用回调函数

28. async 和 await 函数

async、await函数是异步代码的新方式,基于promise实现,使异步代码更像同步代码,await只能在saync函数中使用,不能在普通函数中使用,要成对出现,默认返回一个Promise实例,不能被改变

29. this指向

全局作用域 window

元素的事件绑定函数 当前被绑定的元素

自执行函数 window

定时器 window

构造函数 实例

call,apply,bind 可以改变this指向

箭头函数 本没有this,如果有输出this 指向创建函数时的坐在作用域的this

30.原型

函数: 函数都有 prototype 属性 既是原型 prototype中有 constrouctor属性 指向当前原型所属的类

对象: 对象都有 proto 属性,也是原型,指向当前实例所属类的原型

31.异步回调 (如何解决回调地狱)

promise

generator

async、await

32.前端事件流

事件流描述的是从页面中接受事件的顺序, 事件捕获 目标 冒泡 三个阶段

事件捕获阶段: 目标div在捕获阶段不会接受事件,从document > html > body

事件目标阶段: 事件在div发生并处理,但是事件处理会被看成是冒泡阶段的一部分

事件冒泡: 事件又传播回文档

阻止事件冒泡

  //event.stopPropagation()
  function stopBubble(e){
   if(e && e.stopPropogation){
      e.stopPropogation()      //ie以外的浏览器
   }else{
     window.event.cancelBubble = true   //ie浏览器
   }
  }

//阻止默认行为

function stopDefault(e){
  if(e && e.preventDefault){
     e.preventDefault()
  }else{
  //ie浏览器阻止默认行为
    window.event.returnValue = false
  }
}

return false 既可以阻止事件冒泡,又能阻止默认事件

33.如何判断一个变量是对象还是数组 Object.prototype.toString.call()

let arr = [12,23,32]
Object.prototype.toString.call(arr)  
//[object Array]

千万不要使用typeOf来判断对象和数组,因为这种类型都会返回 object

typeOf() 是判断基本类型的 Boolean,Number,String,symbol,undefined等,对于引用类型,除了function,其他的都会返回object, null也是返回object

instanceOf() 用来判断A是否是B的实例,instanceOf 检查的是原型,不管是Array 和 Object 都会返回true

toString()是object的原型方法,对于Object对象,调用toString()方法就能返回[Object Object]

34.setTimeout 和 setInterval 的执行机制

setInterval 和 setTimeout 是异步任务,因为js是单线程的,所以所有的任务会排队,同步任务进入执行栈,异步任务进入任务队列,当执行栈中的操作完成,任务队列才会进入执行栈中执行

35.splice 和 slice , map 和 forEach , filter() , reduce()的区别

1) slice(start,end) 方法可以从已有数组中返回选定的元素,返回一个新数组,从 start 到 end 的数组方法

注意: 该方法不会更新原数组,而是返回一个子数组

2) splice() 方法在数组中 添加 或 删除 项目,返回被删除的项目(该方法会改变原数组)

splice(index,howmany,item1,...itemx)

index 参数 必须 规定删除或添加的位置

howmany 参数 必须 要删除的数目

item1,...itemx 可选,表示象数组添加新项目

3)map() 会返回一个新的数组,适用于改变数据值的时候,会分配内存空间数组并返回return

4)forEach()不会返回数据,允许callback更改原数组的元素

5)reduce() 接收一个函数作为累加器,最终计算一个值,不会改变原数组的值

6) filter() 创建一个新数组,新数组中的元素是通过检查指定数组中符合条件的所有元素

vue问题

1.聊聊对vue的理解

vue是一个渐进式的js框架。易用,灵活,高效;可以把一个页面分割成多个组件,当其他
页面有相同类似功能时可以让封装的组件进行复用;他是构建用户界面的声明式框架,只关
心图层,不关心具体如何实现的

特点: 1) 数据驱动视图,无需手动操作dom  mvvm
      2) 支持模块化开发
      3) vNode虚拟dom diff算法
     

2.v-model的原理是什么?

vue的双向数据绑定原理
1.比如页面有个input 输入框 绑定的是 username
2.可以获取值 和 修改值 (get/set) 
3.set 方法有一个通知机制,只要你一修改,他马上就会通知 watcher 监视器
4.watcher 就会马上告知虚拟Dom树,user变量发生了改变
5.diff算法
6.虚拟DOM会利用diff算法生成一颗新的Dom树,然后拿两颗Dom树利用diff算法进行比较,比较之后发现是不一样的节点,就会把新的节点更新到Dom树上,同时更新到页面上去
7.vue会给input事件绑定oninput事件,此时就会调用setter方法,改变data里的属性值,这就是v-model的原理
 

3.谈谈对生命周期的理解

beforeCreate阶段:vue实例的挂载元素el和数据对象data都是undefined,还没有初始化

created阶段: vue实例的数据对象data有了,可以访问里面的数据和方法,但是为挂载到DOM,el还没有

beforeMount阶段: vue实例的el和data都初始化好了,但是挂载之前为虚拟的dom节点

mounted阶段:vue实例挂载到真实的dom上,就可以通过DOM获取DOM节点

beforeUpdate阶段:响应式数据更新时调用,发生在虚拟dom打补丁之前,适合在更新之前访问现有的dom

updated阶段:虚拟dom重新渲染和打补丁之后调用,组件新的dom已经更新,避免在这个钩子函数上操作数据,防止死循环

beforeDestory阶段: 实例销毁前调用,实例还可以用,this能获取到实例,常用于销毁定时器,解绑事件

destoryed阶段:实例销毁之后调用,调用后所有事件监听会被移除,所有子实例都被销毁

activted keep-alive专属 组件被激活时使用

deactivated keep-alive专属 组件被销毁时调用

异步请求在哪一步发起:  可以在钩子函数created,beforeMount,mounted中进行异步
请求,因为在着三个钩子函数中,data已经创建,可以将服务器端返回的数据进行赋值

如果异步请求不依赖dom,推荐在created钩子函数中调用异步请求,因为在created钩子
函数中调用异步请求能更快的获取到服务端的数据,减少页面loading时间,ssr不支持
beforeMount 和 mounted 钩子函数,放在created中有助于一致性

4.vue和react有什么区别:

react整体是函数式的思想:把组件设计成纯组件,状态和逻辑都是通过传参的方式传入,都是单向数据流量

vue的思想是响应式的,基于数据可变的,通过对每个属性建立watcher来监听,当属性变化时,响应式的更新对应的虚拟dom

5.vuex的流程

 页面通过 dispatch 异步提交事件到action ,action通过commit把对应参数同步提交
 到mutation。mutation会修改state中对应的值。最后通过getter把对应的值跑出去,
 在页面的计算属性中通过mapGetter来获取state中的值

6.vuex有哪几种状态和属性

  • state:保存着共有数据,数据是响应式的
  • getter: 可以对state进行操作,主要是用来过滤一些数据
  • mutations:定义方法动态修改state中的数据,通过commit提交方法,方法必须是同步的
  • actions: 将mutations里面处理数据的方法变成异步的,异步操作数据,通过store.dispatch来分发actions,把异步的方法写在actions中,通过commit提交mutations,进行修改数据
  • modules:模块化vuex

7.路由的两种模式

hash:即地址栏url中的 # 符号,hash虽然出现在url中,但不会被包含在HTTP请求中,对后端完全没影响,因此改变hash不会重新加载页面

history:利用了HTML5 history interface 中新增的pushState()和 replaceState()方法

8.vue中key的作用

当vue用v-for正在更新已渲染过的元素列表时,它默认用 就地复用 策略。如果数据项的顺序被改变了,vue将不会移动DOM元素来匹配数据项的顺序,而是简单的复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素

key的作用主要是为了更高效的更新虚拟dom

9.routeroute和 router 的区别

$route是路由信息对象,包括path,params,hash,query,fullPath,matched,name等路由信息参数

$router 是 路由实例 对象包括了路由的跳转方法,钩子函数等

10.vue-router 守卫

全局导航守卫:

  import router from './router';   //引入路由
  //路由前置守卫
  router.beforeEach((to,from,next) =>{
    next()
  })
  //路由后置守卫
  router.afterEach((to,from) =>{
     next()
  })
  //路由解析守卫
  router.beforeResolve((to,form,next)=>{
    next();
  })

路由独享的守卫

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

组件内的守卫

  const Foo = {
   template:``,
   beforeRouteEnter(to,from.next){
      //此时不能获取this
      //当守卫执行前,组件实例还没被创建
   },
   beforeRouteUpdate(to,from,next){
     //路由改变的时候触发,例如在id不同的路径跳转的时候
     //由于会渲染同样的组件,因此组件实例会被复用
     //可以访问this
   },
   beforeRouteLeave(to,from.next){
     //导航离开该组件的对应路由时调用,可以用来禁止用户离开
     //可以访问组件实例 this
     //比如还未保存草稿,或者用户离开前
   }
  }

11.axios是什么,怎么使用,描述使用它实现登陆功能的流程

请求后台资源的模块

npm install axios -S //安装装好

然后是发送跨域,需要在配置文件中进行设置 config/index.js 进行设置。在js中使用import进来,然后get/post 。返回在.then函数中如果成功,失败则在.catch函数中

12.vue修饰符

v-stop 阻止组件事件冒泡

v-prevent 阻止事件的默认行为

v-once 只触发一次,元素或者组件包括元素或者组件的所有子节点,首次渲染之后,不在随数据的变化重新渲染

v-self 只触发自己的事件时,才会执行

13.vue项目中的性能优化

1.不要在模板里写过多表达式

2.循环调用子组件的时候添加 key

3.频繁切换使用 v-show,不频繁切换使用 v-if

4.尽量少用float,使用flex布局

5.按需加载需要的组件

6.路由懒加载

14.vue.extend 和 vue.component

extent是构造一个组件的语法器,然后这个组件你可以作用到component这个注册方法里

component可以创建,也可以注册组件

15.MVC 和 MVVM 的区别

MVC:model view controller 模型视图控制器

model:应用程序中用于处理数据逻辑的部分,通常模型对象负责在数据库中存取数据

view:应用程序中用于处理数据显示的部分,通常视图是依据model数据创建的

controller: 应用程序中处理用户交互的部分,负责从视图读取数据,控制用户输入,并向模型发送数据

mvc的思想:controller负责将 model 的数据用 view 显示出来

MVVM:新增了 VM 类

viewmodel层:做了两件事

1)将 模型 转化成 视图,将后端传递的数据转化成所看到的页面 实现方式:数据绑定 2)将 视图 转化成 模型,将所看到的页面转化成后端的数据 实现方式:DOM事件监听

MVVM 和 MVC 的最大区别:实现了 view 和 model 的自动同步,也就是当model的属性改变时。不需要我们再手动操作dom来改变view的显示,而是改变属性后该属性对应的view层自动改变(对应vue数据驱动视图的思想),整体来看精简了很多,简化了业务与界面的依赖,和频繁更新数据的问题,不用再用选择器操作dom元素,因为再mvvm中,view不知道model的存在,model和viewmodel也观察不到view,这种低耦合模式提高了代码的可重用性

但是 vue 也没有完全遵守mvvm的思想,提供了$refs 这个属性来让model可以直接操作view

16.为什么data是一个函数

组件中的data写成一个函数,数据以函数返回值的形式定义,这样每复用一次组件,就会返回一份新的data,类似于给每个组件创建了一个私有数据空间,让各个组件实例维护自己的数据。如果写成对象的形式,就使得所有组件实例共用一份data,就会造成一个变量全都变了的结果

17.vue的组件通信有哪几种方式

1.props 和 $emit

   父组件向子组件传值数据是通过props来传递的,子组件向父组件传值是通过$emit 触发事件来做到的

2.parentparent 和 children

  获取当前组件的父组件(唯一)和当前组件的子组件(数组)

3.attrsattrs 和 listener

  A  =>  B   => C
  可以多层嵌套的组件间传值,(如果需要对数据做中间处理使用vuex)

4.provide 和 inject

5.$refs

6.eventBus

const EventBus = new Vue()
EventBus.$emit(事件名,数据)
EventBus.$on(事件名,data =>{})

7.vuex 状态管理

state , getters , mutations(commit) , actions(dispatch) , modules

18 v-if 和 v-show的区别

v-if会在编译过程中被转化为三元表达式,不满足条件的时候不渲染

v-show 会被编译成指令,条件不满足时将对应节点隐藏

使用场景: v-if适合在运行时很少改变条件,不需要频繁切换条件的场景

v-show适用于需要频繁切换条件的场景

19. vue 内置指令

v-cloak 解决初始化慢导致的页面闪烁

v-bind 绑定属性

v-on 监听dom事件

v-html 赋值 就是变量 innerHTML

v-tetx 更新元素的textContent

v-model 双向数据绑定

v-if、v-else , v-else-if 可以配合template来使用,render函数里的三元表达式

v-show 通过display来显示隐藏

v-for 循环指令,优先级比v-if高,不要和v-if一起使用,注意增加唯一的key值

v-pre 跳过这个元素及子元素的编译过程,以此来加快整个项目的编译速度

20. 怎样理解vue的单向数据流

组件之间传值,子组件没有权利修改父组件的数据,只能请求父组件对原始数据进行修改。这样能防止子组件意外改变父组件的数据,导致应用的数据流向难以理解

注意:在子组件直接使用 v-model 传递过来的prop数据是不规范的写法

如果要改变父组件的prop值,可以在data里面定义一个变量,用prop的值初始化它,之后再用 $emit 通知父组件去修改

21.computed 和 watch 的区别和运用场景

  computed是计算属性,依赖其他属性计算值,并且有缓存,只有当计算值变化才会返回内容,可以设置getter和setter
  watch监听值的变化就会执行回调,在回调中可以进行复杂的逻辑处理
  
  计算属性一般用于模板渲染中
  侦听属性适用于观测某个值的变化去完成一段复杂的逻辑
  

22. v-if和v-for 为什么不建议一起使用

v-for和v-if不要在同一标签中使用,因为解析的时候是先解析的v-for在解析v-if,如果遇到同时使用的时候可以考虑写成计算属性

23.计算属性

计算属性涉及到后期维护,如果在插值中写过多的逻辑计算,导致模板不整洁会导致后期维护困难

为什么要使用计算属性: 避免在模板中放入过多的逻辑,导致模板过重难以维护

计算属性的特性: 基于响应式依赖进行缓存,只有相关依赖发生改变时他们才会重新求值

计算属性的getter和setter有什么用: getter 用来获取计算后得到的值 setter 如果相对计算属性进行赋值的时候,必须要使用 setter

图片.png

常见的兼容问题

png24位的图片在ie浏览器上出现背景 解决方案是做成png8

浏览器默认的margin和padding不同,解决方案是加一个全局的通配符设置为0

ie6双边距bug 快属性float之后,有左右margin的情况下,在ie6显示margin比设置的大(两倍),解决是最后设置一个 display:inline;