于今年3月份辞职之后找工作,整理一下我的面试中遇到的各种面试题。
- 关于盒子模型?
html中的每一个元素都可以看作是一个盒模型,在网页中一个元素由content , padding , border,margin组成,这四部分整体组成一个盒子模型;当元素使用了padding的时候我习惯性加上box-sizing:border-box;
比如一个宽高都是100px,padding:10px;border:10px;margin:10px的div,在ie浏览器中固定宽高的元素不会被padding撑开,所以ie中这个div的盒子模型是width:100px+border:10px+margin:10px;
一般情况下使用padding的时候会连用box-sizing:border-box;这个属性的意义是表示这个元素去遵循padding 在内部不会撑大宽高的盒模型;
- 如何实现一个未知宽高的元素的居中?
假设div的宽高都是100px;
1、div{
margin:auto;
}
2、div{
position: absolute/fixed/relative;
left: 50%;
transform: translateX(-50%);
}
3、div{
position: absolute/fixed/relative;
left: 50%;
margin: 0 0 0 -50px;
}
- postion的几种属性?
static 默认样式,没有效果,不会脱离文档流 relative 相对定位,相对于自己的正常定位进行定位,left,top生效; absolute 绝对定位或者相对于父级的static进行定位,脱离文档流;相对于页面定位; fixed 绝对定位,脱离文档流,相对于浏览器窗口定位; inherit 默认继承父级元素的position属性; - 如何清除浮动?
clear:both; 可以写在有浮动的下一标签上进行清除 父级加伪类元素:after div:after{display:block;clear:both;content:"";visibility:hidden;height:0}
div{zoom:1}
父级标签定义height 可以解决父级标签获取不到高度的问题; overflow:hidden 父级标签加overflow:hidden; - vue的生命周期?vue的完整的生命周期从创建,到初始化数据,再到编译,挂载DOM,渲染,更新,销毁等一系列的一个过程叫做vue的生命周期
创建前后 beforeCreate 基本不用的,el和data还没有初始化,只是一个空壳,无法访问到数据和dom created data初始化完成,el没有,一般在这里做初始化数据的获取也可以更改数据,不会触发updated函数; 挂载前后 beforeMount data和el完成初始化;相关的render函数第一次被调用 mounted 基本上的数据加载请求都在这一阶段,完成挂载 更新前后 beforeUpdate 数据更新前 updated 数据更新 销毁前后 beforeDestory 删除前 destoryed 删除 - vue数据双向绑定的原理?
利用了object.defineProperty()这个方法重新定义了对象获取属性值(get)和设置属性值(set)的操作来实现的。 - vue的路由实现?
1、利用url中的“#”;
2、利用history在html5中新增的方法;
(平常按步骤搭建的vue项目在运行的时候url中会有#,在ruoter的index.js文件的Router下写mode:'history',运行则无#)
- vue中的key?
1、给每个节点做唯一标识;
2、高新更新dom;
3、用v-for更新已经渲染的元素的时候采用就地复用的策略,如果数据项的顺序被改变,vue将不会移动dom元素来匹配数据项的顺序,而是简单的复用此处的每个元素,确保他在特定的索引值下显示已被渲染过的每个元素。
- vue中的指令及用法?
v-if 条件判断,条件为false的时候,元素不会渲染; v-else 与v-if连用,两者只会显示一个 v-show 条件判断,条件为false的时候也会渲染HTML v-for 基于一个数组渲染出一个列表,相当于js里面的遍历,v-for= '( item ,key,index) in list',里面的in也可以写成 of v-bind 动态的绑定一个或者多个属性,简写为‘:’,例如‘:class='{a }'’ , ':style', ':src={a}' v-on 监听事件,简写为‘@’,例如‘@click=show’, '@submit=submit', v-model 一般用于表单上面,可以很轻松的实现数据的双向绑定;例如:
<input v-model='input'>
<p>{{input}}</p>
data(){
return{
input:''
}
}
v-html 渲染HTML标签;例如
<div v-html='div'></div>
data(){
return {
div:"<h1>this is h1</h1>"
}
}
v-text 可以渲染数据,例如
<div v-text='div'></div>
data(){
return{
div:'this is a div'
}
}
- vue中的指令及用法?
- 同步和异步?
同步 可以理解为在一个函数或者方法之后,一直在等待系统的返回消息,这个时候程序是出于阻塞的,只有接收到返回消息或者返回值才会往下执行; 异步 一个方法或者函数执行之后,不比阻塞的等待返回消息或者值,继续执行余下的方法或者事件,当系统接收到返回消息的时候,系统会通知进程
- rem的原理?px,em,rem的区别?
rem 基于HTML根元素,rem布局的本质是等比缩放,一般是基于宽度;
设置HTML的根字体的大小=移动设备宽度/设计稿宽度*100;那么100px=1rem;
var cw = document.documentElement.clientWidth;
if (cw > 750) {
cw = 750;
}
document.getElementsByTagName("html")[0].style.fontSize = 100 * ( cw / 720) + 'px'
em 会继承父级字体大小,改变某个节点的字体大小很可能会影响整个页面; px 绝对单位,按照屏幕像素精确计算; - js的深克隆和浅克隆?
浅克隆 假设B复制来自A,当A改变的时候,B也会发生变化,就叫浅克隆;
例如:
var a={name:'ddd'};
var bs=a;
bs.name='ef';
console.log(a,bs,'ab')==》ef,ef,ab
解决方式:
1、用运算符...
var a={name:'ddd'};
var bs={...a};
bs.name='ef';
console.log(a,bs,'ab')==》ddd,ef,ab
2、Object.assgin()
var a={name:'ddd'};
var bs=Object.assgin({},a);
bs.name='ef';
console.log(a,bs,'ab');==>ddd,ef,ab
1、2只解决了第一层的拷贝问题;
深克隆 假设B没有变化,就是深克隆;
1、JSON.parse(JSON.stringify)
var a={name:{first:'a',last:'b'}};
var bs=JSON.parse(JSON.stringify(a));
bs.name.first='ef';
console.log(a,bs,'ab')==》a没变,b变了
该方法的缺点:
- 会忽略
undefined
- 会忽略
symbol
- 不能序列化函数
- 不能解决循环引用的对象
意思是:假设a中对象是undefined,symbol,函数等,console.log(bs),对象为这些的bs的数组里面不显示;
2、使用 lodash 的深拷贝函数,可以解决上面的缺点;
function deepClone(obj) {
function isObject(o) {
return (typeof o === 'object' || typeof o === 'function') && o !== null
}
if (!isObject(obj)) {
throw new Error('非对象')
}
let isArray = Array.isArray(obj)
let newObj = isArray ? [...obj] : { ...obj }
Reflect.ownKeys(newObj).forEach(key => {
newObj[key] = isObject(obj[key]) ? deepClone(obj[key]) : obj[key]
})
return newObj
}
//例子
let obj = {
a: [1, 2, 3],
b: {
c: 2,
d: undefined
}
}
let newObj = deepClone(obj)
newObj.b.c = 1
console.log(obj,newObj)
- 会忽略