前端面工程师试题

您所在的位置:网站首页 el-table字体居中 前端面工程师试题

前端面工程师试题

2023-04-12 06:27| 来源: 网络整理| 查看: 265

关于HTMLimg标签的title和alt属性有什么区别alt:图片加载失败时,显示在网页上的替代文字title:鼠标(手机端该属性无意义)放在图片上时显示的文字alt是必需属性(但属性值可为空),title非必需图片懒加载的原理

图像是img标记,浏览器根据图像的src属性请求图像,因此惰性加载的关键是当图像不在可视区域时,不给`imgs‘赋值。

懒加载的思路及实现代码详见js实现图片懒加载原理

H5新增了哪些标签?

常见的有:article、aside、audio、video、footer、header、nav、section

H5和H4有什么不同?

H5新特性有: 用于媒体回放的video和audio元素 对本地离线存储的更好的支持 新的特殊内容元素,如article、footer、header、nav、section

简单地说,它更标准,提供更多的多功能支持。更标准、更可读性、更好的性能和更方便的执行。

块级元素、行内元素分别有哪些?

块级元素:div , p , form, ul, li , ol, dl, form, address, fieldset, hr, menu, table 行内元素:span, strong, em, br, img , input, label, select, textarea, cite

SVG和CANVAS的区别?

SVG

表示以XML格式定义图像的可伸缩矢量图形。

CANVAS

通过 JavaScript 来绘制 2D 图形。

二者比较

svg如何调整颜色

标签fill属性设置即可

关于CSScss3新的特性

CSS3边框如border-radius,box-shadow等;CSS3背景如background-size,background-origin等;CSS3 2D,3D转换如transform等;CSS3动画如animation等。

RGBA和透明度

是RGB颜色模型的一个扩展。本质上,在设置元素中添加了一个alpha通道,即一个表示除红色、绿色和蓝色三种颜色之外的透明度的通道。

background属性background-image:设置元素的背景图像。background-origin:规定背景图片的定位区域。background-size :规定背景图片的尺寸。background-repeat:设置是否及如何重复背景图像。word-wrap属性

word-wrap 属性允许长单词或 URL 地址换行到下一行。

注:所有主流浏览器都支持 word-wrap 属性。

基础语法:

word-wrap: normal|break-word;text-shadow属性

text-shadow 属性:向文本设置阴影。

text-shadow基础语法:

text-shadow: 5px 5px 5px #FF0000;

参数分别表示:水平阴影,垂直阴影,模糊距离,阴影颜色;

font-face属性

font-face属性:定义自己的字体

在新的 @font-face 规则中,您必须首先定义字体的名称(比如 myFirstFont),然后指向该字体文件。

border-radius属性

border-radius 属性:是一个简写属性,用于设置四个 border-*-radius 属性。

基础语法:

border-radius: 1-4 length|% / 1-4 length|%;

注:该属性允许您为元素添加圆角边框!

border-image属性

border-image:将图片规定为包围 div 元素的边框

border-image基础语法:

border-image: url(border.png) 30 30 roundbox-shadow属性

box-shadow属性:向框添加一个或多个阴影。(盒阴影)

box-shadow基础语法:

box-shadow: 10px 10px 5px #888888媒体查询

媒体查询定义两套css,当浏览器的尺寸变化时会采用不同的属性。

元素居中的方式有哪些?水平居中

1.行内元素水平居中 利用 text-align: center 可以实现在块级元素内部的行内元素水平居中。此方法对inline、inline-block、inline-table和inline-flex元素水平居中都有效。 此外,如果块级元素内部包着也是一个块级元素,我们可以先将其由块级元素改变为行内块元素,再通过设置行内块元素居中以达到水平居中。

2.块级元素的水平居中 ①将该块级元素左右外边距margin-left和margin-right设置为auto。 ②使用table+margin 先将子元素设置为块级表格来显示(类似),再将其设置水平居中。 display:table在表现上类似block元素,但是宽度为内容宽。 ③使用absolute+transform 先将父元素设置为相对定位,再将子元素设置为绝对定位,向右移动子元素,移动距离为父容器的一半,最后通过向左移动子元素的一半宽度以达到水平居中。 不过transform属于css3内容,兼容性存在一定问题,高版本浏览器需要添加一些前缀。 ④使用flex+justify-content 通过CSS3中的布局利器flex中的justify-content属性来达到水平居中。 ⑤使用flex+margin 通过flex将父容器设置为为Flex布局,再设置子元素居中。

3.多块级元素水平居中 ①利用flex布局 利用弹性布局(flex),实现水平居中,其中justify-content 用于设置弹性盒子元素在主轴(默认横轴)方向上的对齐方式,本例中设置子元素水平居中显示。 ②利用inline-block 将要水平排列的块状元素设为display:inline-block,然后在父级元素上设置text-align:center,达到与上面的行内元素的水平居中一样的效果。

4.浮动元素水平居中 对于定宽的浮动元素,通过子元素设置relative + 负margin 对于不定宽的浮动元素,父子容器都用相对定位 通用方法(不管是定宽还是不定宽):flex布局

垂直居中

1.多行内联元素垂直居中 ①利用flex布局(flex) 利用flex布局实现垂直居中,其中flex-direction: column定义主轴方向为纵向。这种方式在较老的浏览器存在兼容性问题。 ②利用表布局(table) 利用表布局的vertical-align: middle可以实现子元素的垂直居中。

2.块级元素垂直居中 ①使用absolute+负margin(已知高度宽度) 通过绝对定位元素距离顶部50%,并设置margin-top向上偏移元素高度的一半,就可以实现了。 ②使用absolute+transform 当垂直居中的元素的高度和宽度未知时,可以借助CSS3中的transform属性向Y轴反向偏移50%的方法实现垂直居中。但是部分浏览器存在兼容性的问题。 ③使用flex+align-items 通过设置flex布局中的属性align-items,使子元素垂直居中。 ④使用table-cell+vertical-align 通过将父元素转化为一个表格单元格显示(类似 和 ),再通过设置 vertical-align属性,使表格单元格内容垂直居中。

水平垂直居中

1、绝对定位+CSS3(未知元素的高宽) 利用Css3的transform,可以轻松的在未知元素的高宽的情况下实现元素的垂直居中。 CSS3的transform固然好用,但在项目的实际运用中必须考虑兼容问题,大量的hack代码可能会导致得不偿失。 2、flex布局 利用flex布局,其中justify-content 用于设置或检索弹性盒子元素在主轴(横轴)方向上的对齐方式;而align-items属性定义flex子项在flex容器的当前行的侧轴(纵轴)方向上的对齐方式。不能兼容低版本的IE浏览器。 3、flex/grid与margin:auto(最简单写法) 容器元素设为 flex 布局或是grid布局,子元素只要写 margin: auto 即可,不能兼容低版本的IE浏览器。

自适应的方案?viewport方案

配置默认根字号、默认字号、默认设计稿宽度,然后使用postcss插件将代码中的px自动转换成rem,这种方法可以完成使用1080p设计稿再不同手机下的适应方案,所有元素大小均按照1080p下的大小来定义px。配置上述插件后,px单位在编译后会默认转为rem单位,如果不需要被转换,可以将小写的px改成大写的PX或Px。取消使用viewport.js文件,如果遇到不能适配的公共组件,则拷贝一个新的版本,适配新的方案,逐步淘汰老版本。

// 引用该mixin,其中包含了默认的变量等 $default-font-size: 100; // 默认根字号大小,用于换算vw单位 $baseFontSize: 100px; // 默认字号大小,用于计算rem值 $pageWidth: 1080; // 默认的设计稿宽度 @import '@oppobrowser/lib-browser-scss/src/mixins.scss'; //项目的vue.config.js中增加如下postcss配置 // 在css配置项中增加postcss配置,用于px转rem单位,后续合到master后就统一配置了 css: { loaderOptions: { sass: { data: '@import "@/common/scss/variables.scss";', }, postcss: { plugins: [ require('postcss-pxtorem')({ // 把px单位换算成rem单位 rootValue: 100, // 换算的基数(设计图1080的根字体为100) selectorBlackList: [], // 忽略转换正则匹配项 propList: ['*'], }), ], } }rem方案

针对Android4.4以下版本,全部使用rem单位兼容方案,并在head标签内添加脚本重写html根字号的大小,1080p下为100px。并且针对受影响的公共组件写出兼容性代码。

(function(doc, win) { var basicWidth = 1080; var minWidth = 360; var htmlElement = doc.documentElement; var dpr = parseInt(window.devicePixelRatio || 1, 10); var recalc = function() { var clientWidth = htmlElement.clientWidth || (basicWidth / 2); window.rootFontSize = 100 * (clientWidth / basicWidth); clientWidth = clientWidth < minWidth? minWidth : clientWidth; htmlElement.style.fontSize = 100 * (clientWidth / basicWidth) + 'px'; htmlElement.setAttribute("data-dpi", dpr); }; recalc(); if (!win.addEventListener) return; win.addEventListener('resize', recalc, false); })(document, window); 父容器高度塌陷的解决方案?overflow:hidden利用伪元素div::after { display: block; content: ""; clear: both; }添加一个div .cf { clear: both; } ....... ....... 清除浮动的方法有哪些?额外标签法

给谁清除浮动,就在其后额外添加一个空白标签 。 优点:通俗易懂,书写方便。(不推荐使用) 缺点:添加许多无意义的标签,结构化比较差。

给元素small清除浮动(在small后添加一个空白标签clear(类名可以随意),设置clear:both;即可)

父级添加overflow方法

可以通过触发BFC的方式,实现清楚浮动效果。 优点:代码简洁(慎重使用,若该父盒子里还有position定位会引起麻烦) 缺点:内容增多时候容易造成不会自动换行导致内容被隐藏掉,无法显示需要溢出的元素。

注意:别加错位置,是给父亲加(并不是所有的浮动都需要清除,谁影响布局,才清除谁。)

使用after伪元素清除浮动

after方式为空元素的升级版,好处是不用单独加标签了。 优点:符合闭合浮动思想,结构语义化正确 缺点:由于IE6-7不支持:after,使用zoom:1,触发hasLayout。

注意:这个也是给父亲添加 clearfix

使用before和after双伪元素清除浮动

注意:是给父亲添加clearfix

less和sass的区别?

不管是Sass,还是Less,都可以视为一种基于CSS之上的高级语言,其目的是使得CSS开发更灵活和更强大,Sass的功能比Less强大,基本可以说是一种真正的编程语言了,Less则相对清晰明了,易于上手,对编译环境要求比较宽松。考虑到编译Sass要安装Ruby,而Ruby官网在国内访问不了,个人在实际开发中更倾向于选择Less。

关于JS、ES6es6兼容的浏览器版本

支持ie 11+

var,let,const的比较?var声明变量存在变量提升,let和const不存在变量提升let、const都是块级局部变量同一作用域下let和const不能声明同名变量,而var可以继承的方式有那几种?

原型链继承

父类的实例作为子类的原型

借用构造函数继承(伪造对象、经典继承)

复制父类的实例属性给子类

实例继承(原型式继承)

组合式继承

调用父类构造函数,继承父类的属性,通过将父类实例作为子类原型,实现函数复用

寄生组合继承

通过寄生的方式来修复组合式继承的不足,完美的实现继承

es6 extends继承

代码量少,易懂

ES5继承和ES6继承的区别

es5继承首先是在子类中创建自己的this指向,最后将方法添加到this中

Child.prototype=new Parent() || Parent.apply(this) || Parent.call(this)

es6继承是使用关键字先创建父类的实例对象this,最后在子类class中修改this

说说对原型链的理解

原型链,简单理解就是原型组成的链,对象的proto它的是原型,而原型也是一个对象,也有proto属性,原型的proto又是原型的原型,就这样可以一直通过proto想上找,这就是原型链,当向上找找到Object的原型的时候,这条原型链就算到头了。

有哪些数据类型

值类型(基本类型):

字符串(String)、数字(Number)、布尔(Boolean)、对空(Null)、未定义(Undefined)、Symbol。

引用数据类型:

对象(Object)、数组(Array)、函数(Function)。

判断数据类型的方式有哪些typeofinstanceofconstructorObject.prototype.toString.call()数组去重的方式

1、使用set

2、使用 filter()

3、使用 reduce()

const array = [' ', 1, 2, ' ',' ', 3]; ​ // 1: "Set" [...new Set(array)]; ​ // 2: "Filter" array.filter((item, index) => array.indexOf(item) === index); ​ // 3: "Reduce" array.reduce((unique, item) => unique.includes(item) ? unique : [...unique, item], []); ​ ​ // RESULT: // [' ', 1, 2, 3]; 深拷贝和浅拷贝的方式

深拷贝

1、最简单的方法就是JSON.parse(JSON.stringify())

function deepCopy(o) { return JSON.parse(JSON.stringify(o)) } var c = { age: 1, name: undefined, sex: null, tel: /^1[34578]\d{9}$/, say: () => { console.log('hahha') } } // { age: 1, sex: null, tel: {} }

需要注意的是:这种拷贝方法不可以拷贝一些特殊的属性(例如正则表达式,undefine,function)

2、用递归去复制所有层级属性

function deepCopyTwo(obj) { let objClone = Array.isArray(obj) ? [] : {}; if (obj && typeof obj == 'object') { for (const key in obj) { //判断obj子元素是否为对象,如果是,递归复制 if (obj[key] && typeof obj[key] === "object") { objClone[key] = deepCopyTwo(obj[key]); } else { //如果不是,简单复制 objClone[key] = obj[key]; } } } return objClone; }

浅拷贝

object.assign(target,source)

防抖和节流的区别

debounce和throttling 各有特点,在不同 的场景要根据需求合理的选择策略。如果事件触发是高频但是有停顿时,可以选择debounce; 在事件连续不断高频触发时,只能选择throttling,因为debounce可能会导致动作只被执行一次,界面出现跳跃。

二叉树的遍历有几种方法?先序中序后序层序遍历

具体实现方法详见:二叉树遍历的几种常见方法

数组扁平化有几种方法?

二维数组时,可以简单使用flat()方法

let arr = [[1,2],[3,4],[5,6]];

let arr = [[1,2],[3,4],[5,6]].flat(); console.log(arr); // [1,2,3,4,5,6]

如果是多维数组,则flat()将达不到效果,

需要给flat()传一个参数,var newArray = arr.flat([depth]),

参数:depth ,可选,指定要提取嵌套数组的结构深度,默认值为 1。

let arr = [[1,2],[3,4],[5,6]].flat(Infinity); console.log(arr); // [1,2,3,4,5,6]

迭代实现 (ES6扩展运算符…)

const arr = [1,2,[3,4,5,[6,7],8],9,10,[11,[12,13]]]; const flatten = (arr) => { while(arr.some(item=>Array.isArray(item))){ arr=[].concat(…arr); } return arr; } console.log(flatten(arr)); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]

普通递归实现

const arr = [1,2,[3,4,5,[6,7],8],9,10,[11,[12,13]]]; const flatten = (arr) => { let result = []; arr.forEach((item, i, arr) => { if (Array.isArray(item)) { result = result.concat(flatten(item)); } else { result.push(arr[i]) } }) return result; }; console.log(flatten(arr));

高级递归(reduce方法)

const flatten = (array) => array.reduce((acc,cur)=> (Array.isArray(cur)?[…acc,…flatten(cur)]:[…acc,cur]),[])

toString()

该方法利用了 toString 把数组变成以逗号分隔的字符串,然后可通过遍历数组把每一项再变回原来的类型。

const arr = [1,2,[3,4,5,[6,7],8],9,10,[11,[12,13]]]; const flatten = (arr) => arr.toString().split(',').map((item) => +item); console.log(flatten(arr));

[].concat.apply

const arr = [1,2,[3,4,5,[6,7],8],9,10,[11,[12,13]]]; const flatten = (arr) => { while (arr.some(item => Array.isArray(item))){ arr = [].concat.apply([], arr); } return arr; } console.log(flatten(arr));如何同时发多个请求

详情见,promise.all()

使用过的webpack插件

可参考常用的18个webpack插件总结

jquery添加拓展的方式

1、Query.extend(Object);   // jQuery 本身的扩展方法 2、jQuery.fn.extent(Object);  // jQuery 所选对象扩展方法

关于浏览器、HTTP盒模型的差异?

css盒模型本质是一个盒子,它由边距、边框、填充和实际内容组成。盒模型能够让我们在其他元素和周边元素边框之间的空间放置元素。

标准盒与怪异盒的区别在于他们的总宽度的计算公式不一样。标准模式下总宽度=width+margin(左右)+padding(左右)border(左右);怪异模式下总宽度=width+margin(左右)(就是说width已经包含了padding和border值)。标准模式下如果定义的DOCTYPE缺失,则在ie6、ie7、ie8下汇触发怪异模式。当设置为box-sizing:content-box时,将采用标准模式解析计算,也是默认模式;当设置为box-sizing:border-box时,将采用怪异模式解析计算。

什么是跨域?

当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域

跨域解决方法:

jsonp方式代理服务器的方式服务端允许跨域访问(CORS)取消浏览器的跨域限制()登录鉴权怎么处理?HTTP Auth AuthenticationCookie + SessionJWTOAuth

详情见:前端需知道的常见登录鉴权方案

后端返回的错误码及含义?

常见状态代码、状态描述、说明:

200 OK //客户端请求成功400 Bad Request //客户端请求有语法错误,不能被服务器所理解401 Unauthorized //请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用403 Forbidden //服务器收到请求,但是拒绝提供服务404 Not Found //请求资源不存在,eg:输入了错误的URL500 Internal Server Error //服务器发生不可预期的错误503 Server Unavailable //服务器当前不能处理客户端的请求,一段时间后可能恢复正常三次握手的过程?

在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接。

第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认; SYN:同步序列编号(Synchronize Sequence Numbers) 第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态; 第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。

完成三次握手,客户端与服务器开始传送数据

前端性能优化方案有哪些?

详情见:前端性能优化方案都有哪些?

两个项目如何共享cookie

详情见:项目之间Cookie的共享

cookie和session的区别cookie数据存放在客户的浏览器上,session数据放在服务器上。cookie不是很安全,别人可以分析存放在本地的cookie并进行cookie欺骗,考虑到安全应当使用session。session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,考虑到减轻服务器性能方面,应当使用cookie。单个cookie保存的数据不能超过4k,很多浏览器都限制一个站点最多保存20个cookie。除了cookie,还有什么存储方式,说说cookie和localStorage的区别

还有localStorage,sessionStorrage,indexDB等

cookie和localStorage的区别:

cookie数据始终在同源的http请求中携带,即cookie在浏览器和服务器间来回传递

cookie数据还有路径概念,可以限制。cookie只属于某个路径下

存储大小限制也不同,cookie数据不能超过4k,同时因为每次http请求都会携带cookie,都以cookie只适合保存很小的数据,如会话标识。

localStorage虽然也有存储大小的限制,但是比cookie大得多,可以达到5M或更大

localStorage始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;cookie只在设置的cookie过期时间之前一直有效,即使窗口和浏览器关闭。

移动端问题手势事件的应用可以使用touchstart或者touchend事件,来代替click事件,用来触发移动端的点击事件。可以使用touchmove事件代替scroll事件,来检测移动端的滑动事件。并且可以通过touchmove事件,来实施获取滚动条滚动的高度。2X图3X图适配

实际程序开发当中,我们代码中用的值是指逻辑分辨率pt,而不是像素分辨率px,比如我们定义一个按钮的告诉为45,这个45指的是45pt而不是45px。在非Retina屏下1pt=1px,4和4.7Retina屏下1pt=2px,5.5和x下1pt=3px。我们制作不同尺寸的图片,比如@1x为22px,则@2x为44px,@3x为66px,命名分别为image.png,在项目的Assets.xcassets中新建New Image Set,修改名字为image,并把相应尺寸的图片拖放至相应位置。

/* 根据dpr显示2x图/3x图 */ .bg-image(@url){ background-image:~"url('@{url}@2x.png'"; @media(-webkit-min-device-pixel-ratio:3),(min-device-pixel-ratio:3){ background-image:~"url('@{url}@2x.png'"; } } .bg-color(@color){ background-color:@color; }图片在安卓上,有些设备模糊问题

这个问题是devicePixelRatio的不同导致的,因为手机分辨率太小,如果按照分辨率来显示网页,字会非常小,所以苹果系统当初酒把iphone4的960x640像素的分辨率在网页里改为480x320像素,这devicePixelRatio=2。而Android的devicePixelRatio比较乱,值有1.5、2和3.为了在手机里更为清晰地显示图片,必须使用2倍宽高的背景图来代替img标签(一般情况下都是用2倍)。

例如一个div的宽高是100PX x 100PX,背景图必须是200PX x 200PX,然后设置background-size:contain样式,显示出来的图片酒比较清晰了。

固定定位布局键盘挡住输入框内容

通过定时器实时监听是否触发input。如果触发input框,就把固定定位改为静态定位。这样就会把内容顶上去。

function fixedWatch(el){ if(document.activeElement.nodeName=='INPUT'){ el.css('position','static') }else{ el.css('position','fixed') } } setInterval(function(){ fixedWatch($('.mian')) },500)移动端底部input被弹出的键盘遮挡

Element.srollIntoView():方法让当前的元素滚动到浏览器窗口的可视区域内。

// 只要在input的点击事件或者获取焦点的事件中,加入这个api就好了 document.querySelector('#inputed').srollIntoView();click的300ms延迟问题和点击穿透问题

300ms延迟导致用户体验不好。为了解决这个问题,一般在移动端用touchstart、touchend、touchmove、tap(模拟的事件)事件来取代click事件。

方案二:FastClick

FastClick是FTLabs专门为解决移动端浏览器300ms点击延迟问题所开发的一个轻量级的库。FastClick的实现原理是在检测到touchend事件的时候,会通过DOM自定义事件立即触发膜牛一个click事件,并把浏览器在300ms之后的click事件阻止掉。

点击穿透问题

说完移动端点击300ms延迟的问题,还不得不提一下移动端点击穿透的问题。可能有人会想,既然click点击有300ms的延迟,那对于触摸屏,我们直接监听touchstart事件不就好了吗?

使用touchstart去代替click事件有两个不好的地方。

第一:touchstart是手指触摸屏幕就触发,有时候用户只是想滑动屏幕,却触发了touchstart事件,这不是我们想要的结果;

第二:使用touchstart事件在某些场景下可能会出现点击穿透的现象。

什么是点击穿透?

假如页面上有两个元素A和B。B元素在A元素之上。我们在B元素的touchstart事件上注册了一个回调函数,该回调函数的作用是隐藏B元素。我们发现,当我们点击B元素,B元素被隐藏了,随后,A元素触发了click元素。

这是因为在移动端浏览器,事件执行的顺序是touchstart>touchend>click。而click事件有300ms的延迟,当touchstart事件把B元素隐藏之后,隔了300ms,浏览器触发了click事件,但是此时B元素不见了,所以该事件被派发到A元素身上。如果A元素是一个链接,那此时页面就会意外地跳转。

iphone及ipad下输入框默认内阴影

通过以下代码设置样式:

element{ -webkit-appearance:none; }移动端-dpr浅析

dpr=物理像素/css像素

在dpr=2;1px的css像素在设备中是2px的物理像素,这会导致在设备上看上去1px的边框是2px

解决方法:

用transfrom:scale()缩小dpr倍数

在meta标签中设定scale缩小两倍

上下拉动滚动条时卡顿、慢

通过以下代码设置样式:

body{ -webkit-overflow-scrolling:touch; overflow-scrolling:touch; }长时间按住页面出现闪退

通过以下代码设置样式:

element{ -webkit-touch-callout:none; }ios和android下触摸元素时出现半透明灰色遮罩element{ -webkit-tap-highlight-color:rgba(255,255,255,0) }active兼容处理,即伪类:active失效

移动端:active伪类无效的解决方法

webkit mask兼容处理

简单说 CSS中的mask-好好利用mask-image

transiton闪屏

// 设置内连的元素在3D空间如何呈现:保留

3D-webkit-transform-style:preserve-3D;

// 设置进行转换的元素的背面在对面用户时是否可见:隐藏

-webkit-backface-visibility:hidden;

如何解决android手机圆角失效问题?

通过background-clip:padding-box为失效的元素设置样式。

关于VUE双向绑定的原理?

vue.js是采用数据劫持结合发布者-订阅者模式的方式,通过 object.defineproperty劫持各个属性的setter和gettr,在数据 变动时发布消息给订阅者,触发相应的的监听回调。

vue的生命周期有哪些?

从Vue实例创建、运行、到销毁期间,总是伴随着各种各样的事件,这些事件,统称为生命周期。

第一次加载页面会触发哪些钩子函数?

beforeCreate, created, beforeMount, mounted

说说兄弟组件的生命周期

父组件在执行到beforeMount就开始初始化兄弟组件A,兄弟组件A同样执行到beforeMount就初始化兄弟组件B,当兄弟组件B执行beforeMount完的时候,兄弟组件A才开始挂载。在父兄子组件挂载前,各组件的实例已经初始化完成。

keep alive生命周期activated: 页面第一次进入的时候,钩子触发的顺序是created->mounted->activateddeactivated: 页面退出的时候会触发deactivated,当再次前进或者后退的时候只触发activatedcomputed和watch的区别?

计算属性computed :

支持缓存,只有依赖数据发生改变,才会重新进行计算不支持异步,当computed内有异步操作时无效,无法监听数据的变化computed 属性值会默认走缓存,计算属性是基于它们的响应式依赖进行缓存的,也就是基于data中声明过或者父组件传递的props中的数据通过计算得到的值如果一个属性是由其他属性计算而来的,这个属性依赖其他属性,是一个多对一或者一对一,一般用computed5.如果computed属性属性值是函数,那么默认会走get方法;函数的返回值就是属性的属性值;在computed中的,属性都有一个get和一个set方法,当数据变化时,调用set方法。

侦听属性watch:

不支持缓存,数据变,直接会触发相应的操作;watch支持异步;监听的函数接收两个参数,第一个参数是最新的值;第二个参数是输入之前的值;当一个属性发生变化时,需要执行对应的操作;一对多;监听数据必须是data中声明过或者父组件传递过来的props中的数据,当数据变化时,触发其他操作,函数有两个参数。immediate:组件加载立即触发回调函数执行;deep: 深度监听,为了发现对象内部值的变化,复杂类型的数据时使用,例如数组中的对象内容的改变,注意监听数组的变动不需要这么做。注意:deep无法监听到数组的变动和对象的新增,参考vue数组变异,只有以响应式的方式触发才会被监听到。

当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。这是watch和computed最大的区别。

diff算法的作用?

Diff算法的作用是用来计算出 Virtual DOM 中被改变的部分,然后针对该部分进行原生DOM操作,而不用重新渲染整个页面。

首屏加载空白的解决方案?

单页面应用的 html 是靠 js 生成,因为首屏需要加载很大的js文件(app.js vendor.js),所以当网速差的时候会产生一定程度的白屏。

解决办法:

优化 webpack 减少模块打包体积,code-split 按需加载服务端渲染,在服务端事先拼装好首页所需的 html首页加 loading 或 骨架屏 (仅仅是优化体验)服务端开启gzip压缩打包文件分包,提取公共文件包谈谈对keep-alive的理解

在平常开发中,有部分组件没有必要多次初始化,这时,我们需要将组件进行持久化,使组的状态维持不变,在下一次展示时,也不会进行重新初始化组件。

也就是说,kee-alive 是 Vue 内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染 。也就是所谓的组件缓存。

vue性能优化方案?

均衡页面加载文件的大小和数量

项目中小图片图片转base64,通过工具如webpack进行图片压缩,文件进行压缩混淆等vue-router 懒加载,异步路由第三方依赖按需加载,比如使用element-ui框架,但是里面的组件只用到了其中一部分,可以单独建一个引入element组件的文件,在里面引入我们项目中需要的组件,然后vue.use它通过webpack进行处理,有一个externals属性,可以在里面设置不需要打包的文件,比如可以设置将vue、vue-router、element-ui等等设置进去,打包的时候就不会打包他们,然后将vue、vue-router、element-ui等资源在html中引入可以借助开启gzip压缩文件,减小文件大小;生产环境build时不生成map文件

14天考研高分特训营(内赠5G备考干货+1V1定制规划+14节精讲课等)

¥1.00已失效

减少等待通过xhr获取数据的时间

在redis中添加缓存在并发允许且数据量较多的情况下,分页可以交给后端做,利用数据库进行排序后取出需要的分页内容,这样虽然增加了xhr请求,但是单次请求耗费时间会大大降低;后端分页每次取数据不一定是仅取当前分页的数据,可以一次性取当前页以及当前页的前后各两页的数据,这样用户进行前后页的切换时,不需要重新继续发起xhr请求。一些内容固定的数据(但又需要进行管理),可以将这些数据的获取合并为一个请求,每次刷新只需要取一次提前发起xhr请求:可以在dom渲染完成之前就发起xhr请求,而不是等待dom渲染完成之后才进行。created时,或者beforeRouteEnter时就调用。

通过交互,在视觉效果上提升

可以通过一些加载loading动画,以及资源加载完成前,可以通过占位符占位的方式,避免渲染时出现空白页,视觉上提升加载速度优先加载当前用户可视区域的内容,其他内容待用户切换tab或者滚动鼠标或者可视区域加载完成后再继续加载图片预渲染,可以在当前页上根据页面上的跳转链接(或者tab页可能的切换),预渲染一些图片

善用vue的一些属性

v-if与v-show根据具体业务场景适当选取善用kee-alive

将项目根据业务和模块,改造为多页面,而不是紧靠单页面支撑

代码优化

一些前端能做的事情,可以在前端本地做,比如当分页是前端分页的时候,伴随的一些排序、筛选等,也可以由前端实现,节省xhr请求,减少时间损耗通用方法封装为模块,减少代码冗余写一些性能高的代码vue可以兼容的浏览器版本

Vue 不支持 IE8 及以下版本,因为 Vue 使用了 IE8 无法模拟的 ECMAScript 5 特性。但它支持所有兼容 ECMAScript 5 的浏览器。使用Vuex和axios时需要浏览器支持:Promise,而IE并不支持Promise。

vue和jquery的对比

jQuery是使用选择器($)选取DOM对象,对其进行赋值、取值、事件绑定等操作,其实和原生的HTML的区别只在于可以更方便的选取和操作DOM对象,而数据和界面是在一起的。比如需要获取label标签的内容:$("lable").val();,它还是依赖DOM元素的值。

Vue则是通过Vue对象将数据和View完全分离开来了。对数据进行操作不再需要引用相应的DOM对象,可以说数据和View是分离的,他们通过Vue对象这个vm实现相互的绑定。

vue适用的场景:复杂数据操作的后台页面,表单填写页面

jquery适用的场景:比如说一些html5的动画页面,一些需要js来操作页面样式的页面

然而二者也是可以结合起来一起使用的,vue侧重数据绑定,jquery侧重样式操作,动画效果等,则会更加高效率的完成业务需求。

mvvm和mvc的区别

MVVM即Model-View-ViewModel的简写。即模型-视图-视图模型。模型(Model)指的是后端传递的数据。视图(View)指的是所看到的页面。视图模型(ViewModel)是mvvm模式的核心,它是连接view和model的桥梁。它有两个方向:一是将模型(Model)转化成视图(View),即将后端传递的数据转化成所看到的页面。实现的方式是:数据绑定。二是将视图(View)转化成模型(Model),即将所看到的页面转化成后端的数据。实现的方式是:DOM 事件监听。这两个方向都实现的,我们称之为数据的双向绑定。

MVC是Model-View- Controller的简写。即模型-视图-控制器。M和V指的意思和MVVM中的M和V意思一样。C即Controller指的是页面业务逻辑。使用MVC的目的就是将M和V的代码分离。MVC是单向通信。也就是View跟Model,必须通过Controller来承上启下。MVC和MVVM的区别并不是VM完全取代了C,只是在MVC的基础上增加了一层VM,只不过是弱化了C的概念,ViewModel存在目的在于抽离Controller中展示的业务逻辑,而不是替代Controller,其它视图操作业务等还是应该放在Controller中实现。也就是说MVVM实现的是业务逻辑组件的重用,使开发更高效,结构更清晰,增加代码的复用性。

有封装过组件吗?

~可以讲出自己封装过的组件,或者是团队协作时其他大佬封装的组件,前提是只要你能说清楚。

局部混入,多个vue文件操作一个变量,会乱吗

不会,一个vue文件操作后,另外一个vue文件操作时,变量的值还是原来的(建议动手验证一下~)

eventbus事件车兄弟组件传值原理

概念

EventBus是消息传递的一种方式,基于一个消息中心,订阅和发布消息的模式,称为发布订阅者模式。

on('name', fn)订阅消息,name:订阅的消息名称, fn: 订阅的消息emit('name', args)发布消息, name:发布的消息名称 , args:发布的消息

eventbus应用,详情见eventbus使用详情介绍

注:只不过在vue中已经替我们实现好了$emit,$on这些方法,所以直接用的时候去 new Vue()就可以了.

slot插槽类型默认插槽具名插槽作用域插槽vue3.0为什么要用Proxy API替代defineProperty API?

响应式优化。

1.defineProperty API的局限性最大原因是它只针对单例属性做监听。vue2.x中的响应式实现是基于defineProperty中的descriptor,对data中的属性遍历+递归,为每个属性设置了getter、setter。这也就是为什么vue只能对data中预定义的属性做出响应的原因,在vue中使用下标的方式直接修改属性的值或者添加一个预先不存在的对象属性是无法做到settter监听的,这是defineProperty的局限性。

2.Proxy API的监听是针对一个对象的,那么对这个对象的所有操作会进入监听操作,这就完全可以代理所有属性,将会带来很大的性能提升和更优的代码。Proxy可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。

3.响应式是惰性的。在vue2.x中,对于一个深层属性嵌套的对象,要劫持它内部深层次的变化,就需要递归便利这个对象,执行Object.defineProperty把每一层对象数据都变成响应式的,这无疑会有很大的性能消耗。在vue3.0中,使用Proxy API并不能监听到对象内部深层次的属性变化,因此它的处理方式是在getter中去递归响应式,这样的好处是真正访问到的内部属性才会变成响应式,简单可以说是按需实现响应式,减少性能消耗。

vue3.0编译做了哪些优化?

1.生成 Block tree。vue2.x的数据更新并触发渲染的粒度是组件级的,单个组件内部需要遍历该组件的整个vnode数。在2.0里,渲染效率的快慢与组件大小成正相关。并且,对于一些静态节点,又无数据更新,这些遍历都是性能浪费。

vue3.0做到了通过编译阶段对静态模版的分析,编译生成了 Block tree。Block tree是一个将模版基于动态节点指令切割的嵌套区块,每个区域内部的节点结构是固定的,每个区块只需要追踪自身包含的动态节点。所以,在3.0里,渲染效率不再与模版大小成正相关,而是与模版中动态节点的数量成正相关。

2.slot编译优化。在vue2.x中,如果一个组件传入了slot,那么每次父组件更新的时候,会强制使子组件uplate,造成性能浪费。

vue3.0优化了slot的生成,使得非动态slot中属性的更新只会触发子组件的更新。动态slot指的是在slot上面使用v-if,v-for,动态slot名字等会导致slot产生运行时动态变化但是又无法被子组件track的操作。

3.diff算法优化

vue要做权限管理怎么做?如果控制到按钮级别的权限怎么做?

权限验证 | vue-element-admin

说说你对proxy的理解

vue的数据劫持有两个缺点:

无法监听到索引修改数组的指的变化无法监听object的值的变化

所以vue2.x中才会有$set属性的存在

proxy是set中推出的新api,可以弥补以上两个缺点,所以vue3.x版本用proxy替换object.defineproperty。

关于react

angularJs和React区别

React对比Angular是思想上的转变,它并不是一个库,是一种开发理念,组件化,分治的管理,数据与view的一体化,它只有一个中心,渲染view,对于虚拟dom它并没有提高渲染页面的性能,它提供更多的是利用jsx便捷生成dom元素,利用组件概念进行分治管理页面每个部分

redux中间件

中间件提供第三方插件的模式,自定义拦截action->reducer的过程,变为action->middlewares->reducer。这种机制可以让我们改变数据流,实现如异步action,action过滤,日志输出,异常报告等功能。

常用的中间价:redux-logger:提供日志输出;redux-thunk:处理异步操作;redux-promise:处理异步操作;actionCreator的返回值是promise

redux有什么缺点一个组件所需要的数据,必须由副组件传过来,而不能像flux中直接从store取。当一个组件相关数据更新时,即使父组件不需要用到这个组件,父组件还是会重新render,可能会有效率影响,或者需要写复杂的shouldComponentUpdate进行判断。react组件的划分业务组件技术组件?

根据组件的职责通常把组件分为UI组件和容器组件。UI组件负责UI的呈现,容器组件负责管理数据和逻辑。两者通过React-Redux提供connect方法联系起来。

react生命周期函数

一、初始化阶段:

getDefaultProps:获取实例的默认属性

getInitialState:获取每个实例的初始化状态

componentWillMount:组件即将被装载、渲染到页面上

render:组件在这里生成虚拟的DOM节点

componentDidMount:组件真正在被装载之后

二、运行中状态:

componentWillReceiveProps:组件将要接收到属性的时候调用

shouldComponentUpdate:组件接受到新属性或者新状态的时候(可以返回false, ️数据后不更新,阻止render调用,后面的函数不会被继续执行了)

componentWillUpdate:组件即将不能修改属性和状态

render:组件重新描绘

componentdidUpdate:组件已经更新

三、销毁阶段:

componentwillUnmount:组件即将销毁

react性能优化是哪几个周期函数?

shouldComponentUpdate这个方法用来判断是否需要调用render方法重新描绘dom。因为dom的描绘非常消耗性能,如果我们能在shouldComponentUpdate方法中能够写出更优化的dom diff算法,可以极大的提高性能。

react性能优化方案重写shouldComponentUpdate来避免不必要的dom操作使用production版本的React.js使用key来帮助React识别列表中所有子组件的最小变化

简述flux思想

Flux的最大特点,就是数据的“单向流动”。

用户访问ViewView发出用户的ActionDispatcher收到Action,要求Store进行相应的更新Store更新后,发出一个“change”事件View收到“change”事件后,更新页面在react中,refs的作用是什么?

Refs可以用于获取一个DOM节点或者React组件的引用。何时使用refs的好的示例you管理焦点/文本选择,触发命令动画,或者和第三方DOM库集成。你应该避免使用String类型的Refs和内连的ref回调。Refs回调是React所推荐的。

为什么建议传递给setState的参数是一个callback而不是一个对象?

因为this.props和this.state的更新可能是异步的,不能依赖它们的值去计算下一个state。

关于angular框架Angular中组件之间通信的方式

Props down

调用子组件,通过自定义属性传值调用子组件时,绑定自定义事件和上一步方法子组件内部通过Output和EventEmitter来触发事件并传旨angualr的八大组成部分并简单描述

model是Angular开发中的基本单位,是一个容器,可以包含组件、指令、管道等Component是可被反复使用的带有特定功能的视图

Templates是经过指令和管道、组件等增强过的html

Bindings结合着事件绑定、属性绑定、双向数据绑定等扩展html的功能

Directives分为结构性和属性型指令还有其他模块中比如路由模块中的指令等,主要是增强html

Pipes可以对数据做一个筛选、过滤、格式化从而得到目的数据

Service将组件、应用中的可共用的部分,比如数据或者方法等封装成服务以方便DependencyInjection依赖注入

angular中常用的生命周期的钩子函数?

ngOnChanges:当Angular设置其接收当前和上一个对象值的数据绑定属性时响应。

ngOninit:在第一个ngOnChange触发之后,初始化组件/指令。这是嘴常用的方法,用于从后端服务检索模版的数据。

ngDoCheck:检测并在Angular上下文发生变化时执行。

每次更改检测运行时会被调用。

ngOnDestroy:在Angular销毁指令/组件之前消除。取消订阅可观察的对象并脱离事件处理程序,以避免内存泄漏。

组件特定的hooks:

ngAfterContentInit:组件内容已初始化完成

ngAfterContentChecked:在Angular检查投影到其视图的绑定的外部内容之后。

ngAfterViewInit:Angular创建组件的视图后。

ngAfterViewChecked:在Angular检查组件视图的绑定之后

angular中路由的工作原理

Angular应用程序具有路由服务的单个实例,并且每当URL改变时,相应的路由就与路由配置数组进行匹配,在成功匹配时,它会应用重定向,此时路由器会构建ActivatedRoute对象的数,同时包含路由器的当前状态。在重定向之前,路由器将通过运行保护来检查是否允许新的状态。Route Guard只是路由器运行来检查路由授权的接口方法。来激活路由器状态。

解释rjx在angular中的使用场景

Rxjs是在微软所提供的一种异步处理数据的方式,在angular中处理网络通信时用到了。创建一个Observabe并subsribe

比如:this.http.get('').subscribe((data)=>{})

其他git和svn对比

SVN优缺点

优点:

管理方便,逻辑明确,符合一般人思维习惯。易于管理,集中式服务器更能保证安全性。代码一致性非常高。适合开发人数不多的项目开发。

缺点:

服务器压力太大,数据库容量暴增。如果不能连接到服务器上,基本上不可以工作,看上面第二步,如果服务器不能连接上,就不能提交,还原,对比等等。不适合开源开发(开发人数非常非常多,但是Google app engine就是用svn的)。但是一般集中式管理的有非常明确的权限管理机制(例如分支访问限制),可以实现分层管理,从而很好的解决开发人数众多的问题。Git优缺点

优点:

适合分布式开发,强调个体。公共服务器压力和数据量都不会太大。速度快、灵活。任意两个开发者之间可以很容易的解决冲突。离线工作。

缺点:

学习周期相对而言比较长。不符合常规思维。代码保密性差,一旦开发者把整个库克隆下来就可以完全公开所有代码和版本信息。对内容安全策略CSP的理解

内容安全策略 ([CSP])) 是一个额外的安全层,用于检测并削弱某些特定类型的攻击,包括跨站脚本 (XSS (en-US)) 和数据注入攻击等。无论是数据盗取、网站内容污染还是散发恶意软件,这些攻击都是主要的手段。

CSP 被设计成完全向后兼容(除CSP2 在向后兼容有明确提及的不一致; 更多细节查看这里 章节1.1)。不支持CSP的浏览器也能与实现了CSP的服务器正常合作,反之亦然:不支持 CSP 的浏览器只会忽略它,如常运行,默认为网页内容使用标准的同源策略。如果网站不提供 CSP 头部,浏览器也使用标准的同源策略。

为使CSP可用, 你需要配置你的网络服务器返回 Content-Security-Policy HTTP头部 ( 有时你会看到一些关于X-Content-Security-Policy头部的提法, 那是旧版本,你无须再如此指定它)。

除此之外, 元素也可以被用来配置该策略, 例如



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3