一 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>
5.如何理解css的盒模型
可以看到,在标准盒模型下,width 和 height的区域即content的width和height,在标准模式下,一个块的总宽度=width + margin(左右) + padding(左右) + border(左右)
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的区别
相同点:都是保存在浏览器端,且同源的
不同点:
- cookie数据始终在同源的http请求中携带,即cookie在浏览器和服务器间来回传递
- sessionStorage 和 localStorage 不会自动把数据发给服务器,仅在本地保存
- cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下。存储大小限制也不同,cookie数据不能超过4k , 同时因为每次http请求都会携带cookie,所以cookie只适合保存很小的数据
- sessionStorage 和 localStorage 虽然也有存储大小的限制,但是比cookie大得多,可以达到5m或更大。数据有效期不同,sessionStorage 仅在当前浏览器窗口关闭前有效,自然也就不可能持久保持
- localStorage 始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据
- cookie只在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭。作用域不同 sessionStorage 不在不同的浏览器窗口中共享,即使是同一个页面
- 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.移动端的兼容问题
- 给移动端添加点击事件会有300ms的延迟,如果用点击事件,需要引入一个fastclick.js文件,解决300ms的延迟,一般在移动端使用ontouchstart ontouchmove ontouchend
- 移动端点透问题,touchstart早于touchend 早于 click, click的触发是有延迟的,这个时间大概300ms,也就是说我们tap触发之后,蒙层隐藏,此时click还没有触发,300ms以后由于蒙层隐藏,我们的click触发到了下面的a链节上 , 尽量使用touch事件来替换click事件
- 设置缓存手机页面通常在第一次加载后会进行缓存,然后每次刷新都会使用缓存而不是重新向服务器发送请求,如果不希望使用缓存可以设置 no-cache
- 圆角bug 某些安卓手机圆角失效 background-clip:padding-box ; 防止手机中网页的放大和缩小 5.设置用户截止缩放,一般写视口的时候就已经写好了
20 js中同步和异步,以及js事件流
同步:在同一时间只做一件事 异步:在同一时间做多个事,js是单线程的,每次只能做一件事,js运行在浏览器中,浏览器是多线程的,可以在同一时间执行多个任务
21 js中常见的异步任务
回调函数,定时器,ajax,事件绑定 , async await , promise readFile
22. 三次握手和四次挥手
三次握手
- 客户端生成一个随机初始化序号,向服务端发送SYN ,要求建立数据连接
- 服务端也生成一个随机初始化序号,然后还生成一个ack,都发送给客户端,表示可以建立连接 3.客户端发起ack响应报文给服务端,服务端验证ack没问题,建立连接成功
四次挥手
- 客户端发送FIN报文,通知服务器要关闭连接
- 服务器接收到以后,先发送ack报文给客户端,表示已经接收到了消息,但是数据还没传完
- 服务端等数据传完,再发送FIN报文给客户端,表示数据传输完毕
- 客户端发起ack报文,表示已经知晓,这样两边都可以关闭连接了 但是客户端会等2MSL 就是报文传输的最大声生命周期(2) 然后如果没收到服务端的报文,就会关闭连接了
23. 为什么建立连接时三次握手,而断开连接是四次挥手
因为ACK和FIN 一般都会分开发放,从而导致多了一次
24 dom dff原理
对比(diff)渲染更新前后产生的虚拟dom对象的差异化,并产出差异补丁对象,再将差异补丁对象应用到真实的dom节点上
对比的原理:
- 元素类型发生变化,直接替换
- 如果是文本,则比较文本里面的内容,如果是元素就比较当前元素的属性
25.作用域
1.全局作用域
浏览器打开页面时,浏览器会给js代码一个全局的运行环境,这个环境就是全局作用域 , 一个页面就一个全局作用域。全局作用域下有一个window对象 window 是全局作用域下的最大的内置对象,在私有作用域中能获取到全局变量,但是在全局作用域中不能获取私有变量
2.私有作用域
函数执行会形成一个新的私有的作用域(执行多次,形成多个私有作用域)私有作用域在全局作用域中形成,具有包含关系;在一个全局作用域中,可以有很多个私有作用域,在私有作用域下定义的变量都是私有变量,形参也是私有变量,函数体中通过function定义的函数也是私有的,全局作用域不能使用
3.块级作用域
es6新引入的一种作用域,在js中常见到 if{} , for{} ,while{} , try{} , catch{} , switch{}等都是块级作用域 var obj = {} 对象的大括号不是块级作用域,块级作用域中的同一变量不能重复声明
- 上级作用域
函数在哪里定义的,他的上一级作用域就是哪,和函数在那个作用域下执行没有关系
域链:当获取变量对应的值的时候,首先看变量是否是私有变量,如果不是私有变量要到上级作用域中去找,如果上级也没有,就继续往上一级查找,直到找到为止,如果找到全局作用域还是没有,就会报错
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.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.children
获取当前组件的父组件(唯一)和当前组件的子组件(数组)
3.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
常见的兼容问题
png24位的图片在ie浏览器上出现背景 解决方案是做成png8
浏览器默认的margin和padding不同,解决方案是加一个全局的通配符设置为0
ie6双边距bug 快属性float之后,有左右margin的情况下,在ie6显示margin比设置的大(两倍),解决是最后设置一个 display:inline;