CSS相关
- flex实现元素宽度一比二
-
常见的水平垂直方式有几种?
1)、利用绝对定位,先将元素的左上角通过 top:50%和 left:50%定位到页面的中心,然后再通过 translate 来调整元素的中心点到页面的中心。(兼容问题)
2)、利用绝对定位,设置四个方向的值都为 0,并将 margin 设置为 auto,由于宽高固定,因此对应方向实现平分,可以实现水平和垂直方向上的居中。该方法适用于盒子有宽高的情况。
3)、使用 flex 布局,通过 align-items:center 和 justify-content:center 设置容器的垂直和水平方向上为居中对齐,然后它的子元素也可以实现垂直和水平的居中。
4)、另外,如果父元素设置了flex布局,只需要给子元素加上`margin:auto;`就可以实现垂直居中布局 -
清除浮动的方法
1)、在最后一个浮动标签后加一个新标签,给它添加clear:both
2)、 父级添加overflow方法: 可以通过触发BFC的方式,实现清楚浮动效果。必须定义width或zoom:1,同时不能定义height,使用overflow:hidden时,浏览器会自动检查浮动区域的高度
3)、使用after伪元素清除浮动::after
方式,好处是不用单独加标签了。IE8以上和非IE浏览器才支持:after,
4)、使用before和after双伪元素清除浮动 -
0.5px边框如何实现?
-
盒子模型
盒模型分为标准盒模型和怪异盒模型(IE模型)
JavaScript相关
- jQuery和原生获取的DOM有什么区别
1)、jquery选择器得到的jquery对象和标准的 javascript中的document.getElementById()取得的dom对象是两种不同的对象类型,两者不等价;
2)、jQuery无法使用DOM对象的任何方法,同理DOM对象也不能使用jQuery里的方法. 乱使用会报错。 - ReadyState与status
1)、readyState是XMLHttpRequest对象的一个属性,用来标识当前XMLHttpRequest对象处于什么状态
2)、status是XMLHttpRequest对象的一个属性,表示响应的HTTP状态码。0 未初始化状态:此时,已经创建了一个XMLHttpRequest对象 1 准备发送状态:此时,已经调用了XMLHttpRequest对象的open方法,并且XMLHttpRequest对象已经准备好将一个请求发送到服务器端 2 已经发送状态:此时,已经通过send方法把一个请求发送到服务器端,但是还没有收到一个响应 3 正在接收状态:此时,已经接收到HTTP响应头部信息,但是消息体部分还没有完全接收到 4 完成响应状态:此时,已经完成了HTTP响应的接收 1XX 服务器收到请求,需要继续处理。 2XX 请求成功。 3XX 重定向。 4XX 客户端错误。 5XX 服务器错误。 - 常见状态码
100 Continue 该状态码说明服务器收到了请求的初始部分,并且请客户端继续发送。
例如:客户端有一个较大的文件需要上传并保存,但是客户端不知道服务器是否愿意接受这个文件,所以希望在消耗网络资源进行传输之前,先询问一下服务器的意愿。实际操作为客户端发送一条特殊的请求报文,报文的头部应包含:
Expect: 100-continue,此时,如果服务器愿意接受,就会返回 100 Continue 状态码,反之则返回 417 Expectation Failed 状态码。
101 Switching Protocols
表示切换协议。服务器根据客户端的请求切换协议。
例如:WebSocket通信,首先需要客户端发起一次普通的http请求,告诉服务器通信协议将发生改变,转为websocket协议,支持WebSocket的服务器在确认以上请求后,会返回状态码为101的响应。
200 表示从客户端发送给服务器的请求被正常处理并返回; 204 No Content 请求处理成功,但没有任何资源可以返回给客户端,一般在只需要从客户端往服务器发送信息,而对客户端不需要发送新信息内容的情况下使用。 206 Partial Content 是对资源某一部分的请求,该状态码表示客户端进行了范围请求,而服务器成功执行了这部分的GET请求。响应报文中包含由Content-Range指定范围的实体内容。 301 Moved Permanently 永久性重定向,表示请求的资源被分配了新的URL,之后应使用更改的URL 302 Found 临时性重定向,表示请求的资源被分配了新的URL,希望本次访问使用新的URL; 303 See Other 表示请求的资源被分配了新的URL,应使用GET方法定向获取请求的资源 304 Not Modified 客户端发送了一个带条件的GET 请求且该请求已被允许,而文档的内容(自上次访问以来或者根据请求的条件)并没有改变,则服务器应当返回这个304状态码。简单的表达就是:服务端已经执行了GET,但文件未变化。 307 Temporary Redirect 临时重定向,与303有着相同的含义,307会遵照浏览器标准不会从POST变成GET 400 Bad Request 服务器端无法理解客户端发送的请求,请求报文中可能存在语法错误。 401 Unauthorized 该状态码表示发送的请求需要有通过HTTP认证(BASIC认证,DIGEST认证)的认证信息。 403 Forbidden 表示服务器收到请求,但是拒绝提供服务。例如:权限问题,未授权IP等 404 请求的资源不存在,例如,输入了错误的URL或请求后端接口不存在。 500 表示服务器在执行请求时发生了错误,导致无法完成客户端的请求。 503 Service Unavailable 服务器不可访问时给客户端的一种状态 - 跨域
- let var const区别
1)、var 声明的变量是存在变量提升的,let ,const声明的变量不存在变量提升。
2)、在同一作用域下var可以重复声明,let,const不可以重复声明。
3)、var声明的变量不存在块级作用域 let,const声明的变量存在块级作用域。
4)、var和let可以重新赋值 const声明的是一个常量,const声明的变量必须要进行初始化 不能够重新赋值 。
5)、var声明的变量不存在暂时性死区,let,const声明的变量存在暂时性死区。 - iframe组件传值
-
http的长连接和短连接的区别
长连接:客户端与服务端先建立连接,连接建立后不断开,然后再进行报文发送和接收。这种方式下由于通讯连接一直存在。
短连接:客户端与服务端每进行一次报文收发交易时才进行通讯连接,交易完毕后立即断开连接。此方式常用于一点对多点通讯。
短连接的操作步骤是:建立连接——数据传输——关闭连接…建立连接——数据传输——关闭连接
长连接的操作步骤是:建立连接——数据传输…(保持连接)…数据传输——关闭连接 -
说一下常见的检测数据类型的几种方式?
typeof 其中数组、对象、null都会被判断为Object,其他判断都正确
instanceof 只能判断引用数据类型,不能判断基本数据类型 -
判断数组?
1)、Array.isArray(Es6新增)Array.isArray([]) //true
2)、Object.prototype.toString
const arr = ['a','b', 'c']; arr.toString(); // "a,b,c" Object.prototype.toString.call(arr); // "[object Array]"
3)、__proto__(原型)
[1,2,3].__proto__ === Array.prototype; // true
4)、constructor
([]).constructor == Array; // true ({}).constructor == Object; // true
5)、instanceof判断一个对象是否为数组,instanceof会判断这个对象的原型链上是否会找到对应的Array的原型,找到返回 true,否则返回 false。
[] instanceof Array; // true
- 怎么判断空对象?
1)、for...in
通过for...in遍历属性,如果是空对象返回false,否则返回true
2)、Object.keys()(ES6新增)
该方法会返回一个由给定对象的自身可枚举属性组成的数组,可以通过返回数组的长度来判断是否为空对象,若为空对象,该数组长度为0。
3)、将对象转为字符串比较,主要使用JSON.stringify()这个方法对对象进行强转: -
数组如何去重,你有几种方法?
1)、 Array.from(new Set(arr))
2)、利用循环遍历的方式去重:a)、includes:对数组进行循环,对每一个值进行判断,返回数组是否包含某个值 没有就返回false 有就返回truelet arr = [] a.forEach(item=>{ if(!arr.includes(item)) arr.push(item) })
b)、indexOf方法
如果indexOf返回-1,那么就将这个数据添加到新的空数组里,而这个新的数组就是去重后的数组
let arr = [] a.forEach(item=>{ if(arr.indexOf(item) === -1){ arr.push(item) } })
c)、filter+indexOf去重
indexOf返回数组中目标元素首次出现位置的索引值,所以如果遍历的当前元素的索引值与indexOf筛选出来的索引值相等,那么就说明这个元素是第一次出现,就将这个元素过滤到新数组中返回let arr = a.filter((item,index) => { return a.indexOf(item) === index })
-
foreach和map的区别
foreach()方法会针对每一个元素执行提供得函数,该方法没有返回值,是否会改变原数组取决与数组元素的类型是基本类型还是引用类型;
map()方法不会改变原数组的值,返回一个新数组,新数组中的值为原数组调用函数处理之后的值。 -
数组转对象,对象转数组;
1)、数组转对象let arr = ["value1", "value2", "value3"]; let arrObject = {...arr};
2)、对象转数组:Object.keys()
let obj = {0: '1',1: '2'} let arr = [] Object.keys(obj).forEach(item => { arr.push({ label: item, value: obj[item] }) });
-
ajax与axios的区别?
axios是通过Promise实现对ajax技术的一种封装,就像jquery对ajax的封装一样。简单来说就是ajax技术实现了局部数据的刷新,axios实现了对ajax的封装,axios有的ajax都有,ajax有的axios不一定有。
-
Hash和history有什么区别
hash
和history
的认知可能就在hash
的url
里面多了个#
,而history
就不会。1)、hash
模式是一种把前端路由的路径用井号#
拼接在真实url
后面的模式。当井号#
后面的路径发生变化时,浏览器并不会重新发起请求,而是会触发onhashchange
事件。2)、hash
可以改变url
,但是不会触发页面重新加载(hash的改变是记录在window.history
中),即不会刷新页面。3)、
hash变化会触发网页跳转,即浏览器的前进和后退。4)、
VUE相关
- Vue diff算法
- Vuex流程
1)、五种基本属性:分别是 State、 Getter、Mutation 、Action、 Module
2)、a、state => 基本数据(数据源存放地)。 b、getters => 从基本数据派生出来的数据 。c、mutations => 提交更改数据的方法,同步(无法异步) d、actions => 像一个装饰器,包裹mutations,使之可以异步。 e、modules => 模块化Vuex
3)、a、Vuex中所有的状态更新的唯一途径都是mutation,异步操作通过 Action 来提交 mutation实现。 b、mutation支持异步操作,就没有办法知道状态是何时更新的,无法很好的进行状态的追踪。
4)、流程:
(1)通过dispatch去提交一个actions,
(2) actions接收到这个事件之后,在actions中可以执行一些异步|同步操作,根据不同的情况去通过commit去触发mutations,
(3)mutations去更新state数据,state更新之后,就会通知vue进行渲染 - Vue响应式原理
1)通过Object.defineProperty来实现监听数据的改变和读取(属性中的getter和setter方法)实现数据劫持
2)观察者模式(发布者-订阅者):当数据发生改变通过发布者订阅者模式来进行通知进行界面刷新 - Vue数据双向绑定
v-model
1)vue双向数据绑定通过数据劫持结合发布订阅者的方式来实现。也就是视图变化数据变化,数据变化视图变化,其核心是object。defineProperty()
2)object。defineProperty()来劫持各个属性的getter/setter,在数据发生变化的时候发布消息给订阅者,触发相应的监听回调。 - 页面从输入路径到页面加载完成经历了哪些步骤
1)、解析URL:首先会对 URL 进行解析,包括协议名、域名、端口号、路径、查询字段等。
a)、URL 中的协议或者主机名不合法,将会把地址栏中输入的内容传递给搜索引擎。
b)、如果存在非法字符,则对非法字符进行转义后再进行下一过程。
2)、缓存判断:浏览器会判断所请求的资源是否在缓存里,如果请求的资源在缓存里并且没有失效,那么就直接使用,否则向服务器发起新的请求。
3)、DNS解析: 解析URL对应的IP(域名解析的过程实际是将域名还原为IP地址的过程)。
a)、浏览器先检查本地hosts文件是否有这个网址映射关系,如果有就调用这个IP地址映射,完成域名解析。
b)、没找到则会查找本地DNS解析器缓存,如果查找到则返回。
c)、没有找到则会查找本地DNS服务器,如果查找到则返回。
d)、最后迭代查询
4)、TCP三次握手:根据IP建立TCP连接
5)、浏览器向服务器发送HTTP请求。
6)、返回数据: 浏览器接收响应。服务器在收到浏览器发送的HTTP请求之后,会将收到的HTTP报文封装成HTTP的Request对象,并通过不同的Web服务器进行处理,处理完的结果以HTTP的Response对象返回,主要包括状态码,响应头,响应报文三个部分。
7)、页面渲染: 浏览器首先会根据 html 文件构建 DOM 树,根据解析到的 css 文件构建 CSSOM 树,如果遇到 script 标签,则判端是否含有 defer 或者 async 属性,要不然 script 的加载和执行会造成页面的渲染的阻塞。当 DOM 树和 CSSOM 树建立好后,根据它们来构建渲染树。渲染树构建好后,会根据渲染树来进行布局。
8)、关闭TCP连接或继续保持连接 - vue.set有什么用途
通过Vue.set方法设置data属性,Vue.set(data,'名',‘赋值’) - Vue-cli脚手架目录结构
- 计算属性和watch有什么区别?以及它们的运用场景?
区别 :
1)、computed 计算属性:依赖其它属性值,并且computed的值有缓存,只有它依赖的属性值发生改变,下一次获取computed的值时才会重新计算computed的值。
2)、watch 侦听器:更多的是观察的作用,无缓存性,类似与某些数据的监听回调,每当监听的数据变化时都会执行回调进行后续操作。 -
Vue的生命周期是什么 每个钩子里面具体做了什么事情?
开始创建、初始化数据、编译模版、挂载Dom -> 渲染、更新 -> 渲染、卸载 等⼀系列过程,称这是Vue的⽣命周期。
1)、beforeCreate(创建前) :不能访问到data、computed、watch、methods上的方法和数据。
2)、created(创建后) :实例创建完成,实例上配置的 options 包括 data、computed、watch、methods 等都配置完成,但是此时渲染得节点还未挂载到 DOM,所以不能访问到 `$el` 属性。
3)、beforeMount(挂载前)
4)、mounted(挂载后) :在el被新创建的 vm.$el 替换,并挂载到实例上去之后调用。实例已完成以下的配置:用上面编译好的html内容替换el属性指向的DOM对象。完成模板中的html渲染到html 页面中。此过程中进行ajax交互。
5)、beforeUpdate(更新前) :响应式数据更新时调用,此时虽然响应式数据更新了,但是对应的真实 DOM 还没有被渲染。
6)、updated(更新后):在由于数据更改导致的虚拟DOM重新渲染和打补丁之后调用。此时 DOM 已经根据响应式数据的变化更新了。调用时,组件 DOM已经更新,所以可以执行依赖于DOM的操作。然而在大多数情况下,应该避免在此期间更改状态,因为这可能会导致更新无限循环。
7)、beforeDestroy(销毁前) :实例销毁之前调用。关闭一些计时器等。
8)、destroyed(销毁后) :实例销毁后调用,调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。 -
data为什么是一个函数而不是一个对象?new Vue 实例里,data 可以直接是一个对象?
vue中每个组件都有自己数据,且不能互相影响。数据以函数返回值的形式定义,这样当我们每次复用组件的时候,就会返回一个新的data,也就是说每个组件都有自己的私有数据空间,它们各自维护自己的数据,不会干扰其他组件的正常运行。
new Vue 的实例,是不会被复用的,因此不存在引用对象的问题。 -
组件传值
1)、父子组件通信: props/$emit;ref/refs;$attrs / $listeners;$parent / $children
2)、兄弟组件通信: eventBus;vuex
3)、跨级通信: eventBus;Vuex;$attrs / $listeners -
localStorage sessionStorage cookies 有什么区别?
1)、localStorage:以键值对的方式存储 储存时间没有限制 永不生效 除非自己删除记录。
2)、sessionStorage:当与其他页面关闭后被清理相比不能同源窗口共享 是会话级别的存储。
3)、储方式 cookies 数据不能超过4k 同时因为每次http请求都会携带cookie 所有cookie只适合保存很小的数据 如会话标识 -
深拷贝和浅拷贝
1)深拷贝不会随原值的变化而变化,浅拷贝原值发生改变则拷贝的值也会发生改变
2)浅拷贝:Object.assign()、for...in、...展开运算符
3)深拷贝:JSON.parse()和JSON.stringify()、递归。 -
路由导航
1)声明式:router-link 通过标签的方式进行跳转 ;<router-link :to="...">
to里的值可以是一个字符串路径,或者一个描述地址的对象。
2)router.push(...)方法;同样的规则也适用于router.push(...)方法。 -
路由守卫
1)路由守卫的目标是实现这样一个权限判断,在路由跳转之前,会触发一个函数。
2)路由守卫又称导航守卫,指是路由跳转前、中、后过程中的一些钩子函数。官方解释是vue-router提供的导航守卫,要通过跳转或取消的方式来守卫导航。路由守卫分为三种,全局路由、组件内路由,路由独享。
全局路由钩子函数有:beforeEach、beforeResolve、afterEach(参数中没有next)
组件内路由的钩子函数有:beforeRouterEnter、beforeRouteUpdate、beforeRouteLeave
路由独享的钩子函数有:beforeEnter -
虚拟dom与真实dom的区别
1)虚拟dom不会进行回流和重绘
2)虚拟dom进行频繁的修改,然后进行一次性比较并修改dom中需要修改的部分最后在真实dom中进行回流和重绘。
3)虚拟dom(VNode),假的,不是真实的dom
4)真实的dom是一个对象,它的属性非常多,在浏览器中做dom操作,会比较消耗性能;虚拟dom是一个对象,它的属性相比较于真实的dom就比较少---用少量的属性描述一个dom,无法在浏览器中直接显示 -
防抖和节流有什么区别?
1)防抖(debounce):防抖触发高频率事件时n秒后只会执行一次,如果n秒内再次触发,则会重新计算。简单概括:每次触发时都会取消之前的延时调用。
2)节流(thorttle):高频事件触发,每次触发事件时设置一个延迟调用方法,并且取消之前延时
调用的方法。简单概括:每次触发事件时都会判断是否等待执行的延时函数。
3)区别:降低回调执行频率,节省计算资源。
防抖和节流本质是不一样的。
防抖是将多次执行变为最后一次执行,节流是将多次执行变成每隔一段事件执行;
函数防抖一定连续触发的事件,只在最后执行一次,而函数节流一段时间内只执行一次。 -
回流和重绘的区别
1) 重绘:元素样式的改变(但宽高、大小、位置等不变)
如:outline、visibility、color、background-color等只改变自身样式,不会影响到其他元素
2) 回流:元素的大小或者位置发生改变(当页面布局和几何信息发生改变的时候),触发了重新布局导致渲染树重新计算布局和渲染
如添加或删除可见的DOM元素;元素的位置发生变化;元素的尺寸发生变化、内容发生变化(如文本变化或图片被另一个不同尺寸的图片所代替);页面一开始渲染的时候(无法避免); 因为回流是根据视口大小来计算元素的位置和大小的,所以浏览器窗口尺寸变化也会引起回流
3)区别:回流一定会触发重绘,而重绘不一定会回流
ES6相关
- ES6新特性
1)、const 与 let 变量
2)基本的字符串格式化。将表达式嵌入字符串中进行拼接。用${}来界定;ES6反引号(``)直接搞定;
3)、箭头函数(不需要 function 关键字来创建函数、省略 return 关键字、继承当前上下文的 this 关键字)
4)、函数的参数默认值
5)、Spread / Rest 操作符(展开运算符...)
6)、对象和数组解构
7)、for…of 和 for…in
关于优化
- 页面优化有哪些方式
小程序
- 小程序的生命周期函数
一种是小程序的生命周期,一种是小程序中页面的生命周期onLoad() 页面加载时触发,只会调用一次,可获取当前页面路径中的参数。
nShow() 页面显示/切入前台时触发,一般用来发送数据请求;
onReady() 页面初次渲染完成时触发, 只会调用一次,代表页面已可和视图层进行交互。 onHide() 页面隐藏/切入后台时触发, 如底部 tab 切换到其他页面或小程序切入后台等。 onUnload() 页面卸载时触发,如redirectTo或navigateBack到其他页面时。 -
微信小程序架构原理
小程序本质就是一个单页面应用,所有的页面渲染和事件处理,都在一个页面内进行,可以通过微信客户端调用原生的各种接口;
架构,是数据驱动的架构模式,它的UI和数据是分离的,所有的页面更新,都需要通过对数据的更改来实现;
技术,采用JavaScript、WXML、WXSS三种技术进行开发;
功能可分为webview和appService两个部分; webview用来展现UI,appService有来处理业务逻辑、数据及接口调用; 两个部分在两个进程中运行,通过系统层JSBridge实现通信,实现UI的渲染、事件的处理等。 -
如何实现下拉刷新
监听用户下拉刷新事件。
1)、需要在app.json
的windowwindowwindow选项中或页面配置中开启enablePullDownRefresh
。
2)、可以通wx.startPullDownRefresh触发下拉刷新,调用后触发下拉刷新动画,效果与用户手动下拉刷新一致。
3)、当处理完数据刷新后,wx.stopPullDownRefresh可以停止当前页面的下拉刷新。 -
常用的小程序请求接口的方式
HTTPS 请求(wx.request)、上传文件(wx.uploadFile)、下载文件(wx.downloadFile) 和 WebSocket 通信(wx.connectSocket) -
简述下 wx.navigateTo(), wx.redirectTo(), wx.switchTab(), wx.navigateBack(), wx.reLaunch()的区别?
wx.navigateTo():保留当前页面,跳转到应用内的某个页面。但是不能跳到 tabbar 页面 wx.redirectTo():关闭当前页面,跳转到新的页面(类似重定向)。但是不允许跳转到 tabbar 页面
wx.switchTab():跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面
wx.navigateBack():关闭当前页面,返回上一页面或多级页面。可通过 getCurrentPages() 获取当前的页面栈,决定需要返回几层
wx.reLaunch():关闭所有页面,打开到应用内的某个页面 -
登录流程?
登录流程是调wx.login获取code传给后台服务器获取微信用户唯一标识openid及本次登录的会话密钥(session_key)等)。拿到开发者服务器传回来的会话密钥(session_key)之后,前端要保存wx.setStorageSync('sessionKey', 'value')
持久登录状态:session信息存放在cookie中以请求头的方式带回给服务端,放到request.js里的wx.request的header里
-
微信小程序阻止事件冒泡
uniapp阻止事件冒泡:将子类的点击事件@click写成@click.stop
小程序阻止事件冒泡:将子类的点击事件bindtap写成cachtap