问答(45min)
- 自我介绍
- Vue通信机制有哪些
1
2
3父子组件通信:props/$emit、$parent/$children和$ref、provide/inject、$attrs/listeners,
兄弟组件通信:Bus中央事件总线(使用了Vue.$emit和Vue.$on),Vuex
跨级组件通信:Bus、Vuex、provide/inject、$attrs/listeners, - 水平垂直居中实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19.parent{
position:relative;
}
.box{
width:100px;
height:100px;
position:absolute;
top:50%;
left:50%;
transform:translate(-50%,-50%)
//或者
margin-left:-50px;
margin-top:50px;
}
.box{
display:flex;
justify-content:center;
align-itrem:center
} - 实现一个左边固定,右边自适应布局
1
2
3
4
5
6<body>
<div class="parent">
<div class="left"></div>
<div class="right"></div>
</div>
</body>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
551. float: left+ margin-left;float使左边的元素脱离文档流,右边的元素可以和左边的元素显示在同一行,设置margin-left让右边的元素不覆盖掉左边的元素, 代码如下:
.left {
float: left;
width: 200px;
height: 100px;
background-color: green;
}
.right {
margin-left: 200px;
height: 100px;
background-color: yellow;
}
2. position: absolute + margin-left左边绝对定位,右边设置margin-left,代码如下:
.left {
position: absolute;
width: 200px;
background-color: green;
height: 100px;
}
.right {
margin-left: 200px;
background-color: yellow;
height: 100px;
}
3. flex布局可以使两个子元素显示在同一行,只要左边的宽度固定,就可以实现效果, 代码如下:
.parent {
display: flex;
margin: 0 auto;
max-width: 1000px;
height: 100px;
}
.left {
width: 200px;
background-color: green;
}
.right {
flex: 1;
background-color: yellow;
}
4.float+overflow:hidden 这种办法主要通过 overflow 触发 BFC,而 BFC 不会重叠浮动元素
.left {
float: left;
width: 200px;
height: 100px;
background-color: green;
}
.right {
overflow: hidden;
height: 100px;
background-color: yellow;
} - 跨域是啥?跨域有哪些?
1
2
3
4
5
6
7浏览器同源策略:同协议、域名、端口
document.domain+ iframe
JSONP
window.postMessage()
CORS
> 普通跨域请求:只需服务器端设置Access-Control-Allow-Origin;浏览器发现这次跨源AJAX请求是简单请求,就自动在头信息之中,添加一个Origin字段
> 带cookie跨域请求:前后端都需要进行设置;根据xhr.withCredentials字段判断是否带有cookie;服务端同意带cookie:Access-Control-Allow-Credentials: true;Access-Control-Allow-Origin就不能设为星号 - Vue父子组件的执行流程
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21创建初始化阶段:
父:beforeCreate
父:created
父:beforeMount
子:beforeCreate
子:created
子:beforeMount
子:mounted
父:mounted
更新组件阶段:
父:beforeUpdate
子:beforeUpdate
子:updated
父:updated
销毁阶段:
父:beforeDestroy
子:beforeDestroy
子:destroyed
父:destroyed - 浏览器一帧发生了啥?
略 - 原生Ajax实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27function myAjax(url,method='GET',data=null) {
var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP')
data = data ? queryStringify(data) : data
if(method == 'POST') {
xhr.open(method,url,true)
xhr.setRequestHeader('content-type','application/x-www-form-urlencoded')
xhr.send(data)
}else{
if(data) url = url + '?' + data
xhr.open(method,url,true)
xhr.send()
}
xhr.onreadystatechange = function() {
if(xhr.readystate == 4) {
if(xhr.state == 200) {
console.log(xhr.responseText)
}
}
}
function queryStringify(obj) {
var res = ''
for(var key in obj) {
res += key + '=' + obj[key] + '&'
}
return res.substring(0,res.length - 1)
}
} - let,const,var区别
1
2
3let,const 块级作用域,无声明提前;
var无块级作用域,声明提前;
const 一般定义常量(声明要赋值,不然报错),保存基本数据类型或地址指针,不能改变其保存的值;但可以改变其对象的属性(因为保存的对象地址指针并没有改变); - 怎么实现const里面的属性不能修改?
1
2
3Object.defineProperty(obj,'a',{writable:false})
Object.freeze(obj) //冻结 不能修改属性 相当于writable:false
Object.seal(obj) //封存 不能删除 相当于configurable:false - Promise.all() 怎么实现?这么知道执行完成了?
1
2用处:并行执行一系列异步操作,返回结果集。
详解:https://www.jianshu.com/p/c8af0c130ccb - 原型链是啥?
1
2JavaScript是面向对象的,每个实例对象都有一个__proto__属性,该属性指向它的原型对象,这个实例对象的构造函数有一个原型属性prototype,与实例的proto属性指向同一个对象。当一个对象在查找一个属性的时候,自身没有就会根据__proto__向它的原型进行查找,如果都没有,则向它的原型的原型继续查找,直到查到Object.prototype.proto_为null,这样也就形成了原型链。
作用:共享属性和方法 - new的原理
首先新建一个对象,链接到原型,绑定this,返回这个对象。1
2
3
4
5
6
7
8function New(Fn) {
let obj = {}
let arg = Array.prototype.slice.call(arguments, 1)
obj.__proto__ = Fn.prototype //链接到原型
obj.__proto__.constructor = Fn //构造函数改变
Fn.apply(obj, arg) //绑定this
return obj
} - this的指向有哪些?
1
2
3
4
5(1) 作为函数调用,非严格模式下,this指向window,严格模式下,this指向undefined;
(2) 作为某对象的方法调用,this通常指向调用的对象。
(3) 使用apply、call、bind 可以绑定this的指向。
(4) 在构造函数中,this指向新创建的对象
(5) 箭头函数没有单独的this值,this在箭头函数创建时确定,它与声明所在的上下文相同。 - 怎么改变this的指向?
call()、bind()、apply() - call()、bind()、apply() 区别
首先他们都可以改变this的指向;在传参方面,第一个参数都是目标对象(要把this指向的对象),其他参数;call() 方法接受的是一个参数列表,而 apply() 方法接受的是一个包含多个参数的数组。bind改变this不会立即执行,call、apply会立即执行; - Vue数据响应式原理
略 - css盒子模型、BFC
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20盒子组成部分 = 内容(content) + padding(内边距) + border(边框) + margin(外边距)
标准盒模型中width指的是内容区域content的宽度;height指的是内容区域content的高度。
怪异盒模型中的width指的是内容、边框、内边距总的宽度(content + border + padding);height指的是内容、边框、内边距总的高度
改变box-sizing:
> content-box: 默认值,border和padding不算到width范围内,可以理解为是W3c的标准模型(default)
> border-box:border和padding划归到width范围内,可以理解为是IE的怪异盒模型
> padding-box:将padding算入width范围
BFC(Block formatting context)直译为"块级格式化上下文"。它是一个独立的渲染区域;
BFC的布局规则
内部的Box会在垂直方向,一个接一个地放置。
Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠。
每个盒子(块盒与行盒)的margin box的左边,与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
BFC的区域不会与float box重叠。
BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
计算BFC的高度时,浮动元素也参与计算。
如何创建BFC
> 1、float的值不是none。
> 2、position的值不是static或者relative。
> 3、display的值是inline-block、table-cell、flex、table-caption或者inline-flex
> 4、overflow的值不是visible - 父元素高度塌陷解决方案
1
2
3
4(1)给父元素设置高度
(2)给父元素添加:overflow:hidden/auto/scroll都可以清除浮动
(3)给浮动元素末尾添加空标签,给空标签添加clear:both
(4)伪元素清除法:::after{content:"";display:block;clear: both;height:0;overflow: hidden;visibility: hidden;} - requestAnimationFrame/requestIdleCallback
略 - session、cookie、localStorage 、sessionStorage
1
2
3
4
5
6
7
8cookie机制:如果不在浏览器中设置过期时间,cookie被保存在内存中,生命周期随浏览器的关闭而结束,这种cookie简称会话cookie。如果在浏览器中设置了cookie的过期时间,cookie被保存在硬盘中,关闭浏览器后,cookie数据仍然存在,直到过期时间结束才消失。
localStorage:localStorage的生命周期是永久的,关闭页面或浏览器之后localStorage中的数据也不会消失。localStorage除非主动删除数据,否则数据永远不会消失;
sessionStorage的生命周期是在仅在当前会话下有效。sessionStorage引入了一个“浏览器窗口”的概念,sessionStorage是在同源的窗口中始终存在的数据。只要这个浏览器窗口没有关闭,即使刷新页面或者进入同源另一个页面,数据依然存在。但是sessionStorage在关闭了浏览器窗口后就会被销毁。同时独立的打开同一个窗口同一个页面,sessionStorage也是不一样的。
setItem (key, value) —— 保存数据,以键值对的方式储存信息。
getItem (key) —— 获取数据,将键值传入,即可获取到对应的value值。
removeItem (key) —— 删除单个数据,根据键值移除对应的信息。
clear () —— 删除所有的数据
key (index) —— 获取某个索引的key - HTTP强缓存和协商缓存
略 - 有缓存返回的状态码(200)
- 页面布局响应实现?(媒体查询)
- http网络状态码有哪些(200、301、302、304、404、500)
- 301和302的区别(永久重定向、临时重定向)
- 前端安全XSS、CSRF(跨站脚本攻击、跨站请求伪造)
- 说说Vue的mixins?(不咋了解 ,逻辑相同提取公共代码)非全面(有些想不起来了)
1
2
3两个组件引入同一个mixins,混入对象的值在两个组件中是相互独立的。
组件中和mixins中有同样的方法,组件中的会覆盖mixins中的;
如果mixins和组件中含有相同的生命钩子函数,会先执行mixins里面的,然后执行组件中的编程题 (20min)
- JSONP实现
1
2
3
4
5function Jsonp(src){
var script = document.createElement('script')
script.src = src
document.getElementsByTagName('head')[0].appendChild(script)
} - 大数相加
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45// input: a,b (string)
//output: string
function bigAdd(a,b) {
let aLen = a.length
let bLen = b.length
let len = aLen > bLen ? aLen : bLen //取最长的字符串
//以 0 补位
if(aLen > bLen){
var str = ''
for(var i = 0; i < (aLen - bLen); i++) {
str += '0'
}
b = str + b
}else{
var str = ''
for(var i = 0; i < (bLen - aLen); i++) {
str += '0'
}
a = str + a
}
//反转字符串,从个位开始计算
a = a.split('').reverse()
b = b.split('').reverse()
//字符串转number
a = a.map((value,index)=>{
return parseInt(value)
})
b = b.map((value,index)=>{
return parseInt(value)
})
let carryAdd = 0 //进位
let res = []
for(var i = 0; i < len; i++) {
if(a[i] + b[i] + carryAdd >= 10) {
res[i] = a[i] + b[i] - 10 + carryAdd
carryAdd = 1
if(i == len - 1) res[i + 1] = 1 //最后一位进位
}else{
res[i] = a[i] + b[i] + carryAdd
carryAdd = 0
}
}
return res.reverse().join('')
}
console.log(bigAdd('369222222','359222222'))