中级前端常见面试题(附答案),持续更新
文章目录
- Q:JS有哪些数据类型?
- 7种基本类型
- 1种引用类型
- Q:ES6数据结构 Set / Map
- Set
- Map
- Q:call, apply, bind 用法和区别
- call() 和 apply()
- bind()
- Q:new 的执行过程
- 1. 在内存中创建了一个实例对象(内容为空)
- 2. 设置该实例对象的\__proto__属性指向构造函数的prototype原型对象
- 3. 使用该实例对象stu1调用构造函数,改变构造函数中的this指向为实例对象stu1
- 4. 返回刚刚创建好的实例对象
- Q:JS常见的内存泄漏
- 1. 意外的全局变量
- 2. 被遗忘的计时器或回调函数
- 3. 脱离DOM的引用
- 4. 闭包
- Q:cookie、sessionStorage、localStorage的区别?
- cookie
- sessionStorage
- localStorage
- Q:跨域解决方案
- 1. cors 跨域资源共享
- 2. Jsonp
- 3. nginx代理
- 4. postMessage API
- Q:常见状态码
- 1XX:信息性状态码
- 2XX:成功状态码
- 3XX:重定向状态码
- 4XX:客户端错误状态码
- 5XX:服务器错误状态码
- Q:创建 Ajax 过程
- Q:浏览器进程和线程
- 标签页进程
- Browser进程(浏览器主进程)
- 插件进程
- GPU进程
- Render进程(浏览器内核,即浏览器渲染进程)
- Q:从输入URL到页面加载发生了什么?
- 一、DNS解析(网址->IP地址)
- 二、TCP连接(三次握手)
- 三、 客户端发送HTTP请求
- 四、服务端处理请求,并返回HTTP报文
- 五、浏览器解析并渲染页面过程
- 六、TCP连接结束(四次挥手)
- Q:JS Event Loop 事件循环
- heap 堆(主要用于内存分配)
- tack 执行栈/方法调用栈(先进后出)
- task queue 任务队列(异步)
- microtask 微任务(优先级高)
- macrotask 宏任务(优先级低)
- 事件循环过程
- Q:前端异常监控
- 基本异常
- 全局异常
- Promise内部异常
- vue异常
- Q:vue生命周期
- Q:Vue Router 导航守卫
- 全局守卫
- 路由独享的守卫
- 组件内的守卫
- Q:盒模型
- 标准盒模型
- IE盒模型
Q:JS有哪些数据类型?
7种基本类型
- 数字 number
- 字符串 string
- 布尔值 boolean
- undefined
- null
- symbol(ES6)
- bigint(ES10)
1种引用类型
- 对象 object
Q:ES6数据结构 Set / Map
ES6两个新的存储数据的方式,相比Object的优点:
- 纯Hash,性能比Object好很多;
- 自带方法高效简洁;
- 用法与 Java 的 HashSet、HashMap 相似。
Set
Set 与 Array 的关系
- 类似于数组的数据结构,成员的值都是唯一的,没有重复的值;
- Array 是索引集合,Set是键集合,只有键值,没有索引和键名(或者说键名和键值是同一个值);
- Array 的元素按照索引值排序,Set 的元素按照插入顺序排序;
- Set 是纯hash,性能比 Array 好。
Set 特性
- 元素不重复;
- 遍历顺序:插入顺序;
- 没有键只有值,可认为键和值两值相等;
- 添加多个NaN时,只会存在一个NaN;
- 添加相同的对象时,会认为是不同的对象;
- 添加值时不会发生类型转换(5 !== “5”);
- keys()和values()的行为完全一致,entries()返回的遍历器同时包括键和值且两值相等;
Set 常用API
- add() 添加
const mySet = new Set()
mySet.add(123)
mySet.add(567)
mySet.add("abc")
console.log(mySet) // Set[3] {123, 567, "abc"}
- delete() 删除。根据是否有该元素,返回 true 或 false
mySet.delete(123) // true
console.log(mySet) // Set[2] {567, "abc"}
- has() 判断是否存在某元素,返回 true 或 false
mySet.has(567) // true
- size() 获取Set元素的数量
mySet.size // 2
- forEach / for of 遍历
mySet.forEach(val => {console.log(val)
})
// 567
// "abc"for (val of mySet) {console.log(val)
}
// 567
// "abc"
Map
Map 与 Object 的关系
- 类似于对象的数据结构,Object 的键只能是简单数据类型(string、number、symbol),Map 的键可以是任意数据类型
- Map 的元素按照插入顺序排序,Object 没有顺序;
- Map 继承自 Object 对象;
- Map 是纯hash,性能比 Object 好。
Map 特性
- 遍历顺序:插入顺序;
- 对同一个键多次赋值,后面的值将覆盖前面的值;
- 对同一个对象的引用,被视为一个键;
- 对同样值的两个实例,被视为两个键;
- 键跟内存地址绑定,只要内存地址不一样就视为两个键;
- 添加多个以NaN作为键时,只会存在一个以NaN作为键的值;
- Object结构提供字符串—值的对应,Map结构提供值—值的对应;
Map 常用API
- set() 添加
const person = new Map()
person.set("name", "无止尘")
person.set("age", 26)
person.set("hobby", ["篮球", "电影", "摄影"])
console.log(person) // Map(3) {"name" => "无止尘", "age" => 27, "hobby" => Array(3)}
person.set("name", "Truman") // 添加同键名元素会覆盖原值,不会重复添加
- delete() 删除。根据是否有该元素,返回 true 或 false
person.delete("age") // true
console.log(person) // Map(3) {"name" => "Truman", "hobby" => Array(3)}
- get() 获取
person.get("age") // 26
- has() 判断是否存在某元素,返回 true 或 false
person.has("name") // true
person.has("gender") // false
- size() 获取Map元素的数量
person.size // 3
- forEach / for of 遍历
// 6. forEach / for of 遍历
person.forEach((value, key) => {console.log(value, key)
})
// "Truman", "name"
// ["篮球", "电影", "摄影"], "hobby"for ([key, value] of person) {console.log(key, value)
}
// "name", "Truman"
// "hobby", ["篮球", "电影", "摄影"]
Q:call, apply, bind 用法和区别
call() 和 apply()
作用:调用函数,并修改函数运行时的this指向
fn.call(thisArg, arg1, arg2, ...)
fn.apply(thisArg, [arg1, arg2, ...])
// thisArg 当前调用函数this的指向对象
// arg1, arg2... 传递的参数
- 调用函数
this.name = "张三"
function fn(x, y) {console.log(this)console.log(this.name)console.log(x + y)
}
fn(3, 4) // window对象; "张三"; 7
fn.call() // window对象; "张三"; NaN
fn.call(null, 2, 4) // window对象; "张三"; 6
fn.bind(null, [3, 4]) // // window对象; "张三"; 7
- 修改函数运行时的this指向
const obj = {name: "李四"
}
fn.call(obj, 5, 4) // obj对象; "李四"; 9
fn.bind(obj, [3, 4]) // obj对象; "李四"; 7
场景
- 借用构造函数,继承父类的属性;
- 借用其他对象的方法
// 例:伪数组借用数组的方法添加成员
var fakeArr = {0:'a',1:'b',length: 2
};
// 数组的push()方法内部的this原本指向数组,改为指向fakeArr
Array.prototype.push.call(fakeArr, 'newItme');
// fakeArr现在的结果为
fakeArr = {0:'a',1:'b',2:'newItem',length: 3
}
区别
- call(thisArg, [val1], [val2], [val3])
第一个参数是改变后的 this 指向,其后参数都是要传入函数的元素; - apply(thisArg, [val1, val2, val3])
第一个参数是改变后的 this 指向,第二个参数必须是数组,apply 可以把数组每一项展开传入函数。
var arr = [5,1,3,6];
// 使用apply()调用Math.max方法,不需要改变该方法的this指向,所以第一个参数是Math或者null
// 需要把数组里每一项展开,所以第二个参数传入数组
Math.max.apply(Math, arr);
bind()
作用
不会调用函数,会返回一个新的函数。该函数的第一个参数是绑定的 this 指向,原函数中的参数通过第二个参数传递。
fn.bind(thisArg, val)
场景
var obj = {name: '张三',age: 18,say: () => {setInterval(// function(){}.bind(this) 生成一个新的函数,该函数内部this指向原函数的this,原函数是obj调用的,所以this指向objfunction(){console.log(this)}.bind(this),1000)}
};
obj.say();
Q:new 的执行过程
/// 构造函数:
const Student = function(name, age) {this.name = namethis.age = age
}
使用new关键字调用构造函数 Student,分为四步:
1. 在内存中创建了一个实例对象(内容为空)
var stu1 = {};
2. 设置该实例对象的__proto__属性指向构造函数的prototype原型对象
stu1.__proto__ == Student.prototype;
3. 使用该实例对象stu1调用构造函数,改变构造函数中的this指向为实例对象stu1
Student('张三', 20).call(stu1);
4. 返回刚刚创建好的实例对象
Q:JS常见的内存泄漏
1. 意外的全局变量
2. 被遗忘的计时器或回调函数
3. 脱离DOM的引用
4. 闭包
Q:cookie、sessionStorage、localStorage的区别?
cookie
cookie存储的数据会固定携带在请求头中,每次发送请求都会传输,浪费带宽。
// 设置cookie
setcookie('name', '张三', time()+3600)
有效范围:当前目录及子目录有效,上级目录无效;
生命周期:不设置或设置为-1,关闭浏览器即失效;设置为时间戳,则该时间失效;
储存大小:约4k;
数据类型:只能存储字符串类型的数据;
sessionStorage
// 获取文本框内容
var val = document.querySelector('input').value; //JS方法
// 存储文本框内容
window.sessionStorage.setItem('val', val);
// 读取该数据
window.sessionStorage.getItem('val');
// 删除该数据
window.sessionStorage.removeItem('val');
// 清空所有数据
window.sessionStorage.clear();
有效范围:同一页面内共享,不能跨域;
生命周期:关闭浏览器就失效;
存储大小:约5M;
数据类型:只能存储字符串类型的数据;对象类型的数据用 JSON.stringify() 编码后存储。
注:sessionStorage 和 session 无关
localStorage
// 获取文本框内容
var val = $('input').val(); //jQuery方法
// 存储文本框内容
window.localStorage.setItem('val', val);
// 使用该数据
window.localStorage.getItem('val');
// 删除该数据
window.localStorage.removeItem('val');
// 清除所有数据
window.localStorage.clear();
有效范围:同一域内多窗口共享,不能跨域;
生命周期:永久有效,除非手动删除浏览器缓存;
存储大小:约20M;
数据类型:只能存储字符串类型的数据,对象类型的数据用 JSON.stringify() 编码后存储。
Q:跨域解决方案
参考资料:前端常见跨域解决方案(全)
什么是跨域?
跨域:不同源的脚本操作其他源下的对象,读写其他源的资源。
什么是同源?
同源策略是浏览器的安全功能,阻止跨域。目的是防止恶意网站窃取数据,保护信息安全。
同源:同协议,同域名,同端口号
1. cors 跨域资源共享
CORS的基本思想就是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功还是失败。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。在服务器端声明不用同源策略:
header(‘Access-Control-Allow-Origin: *’) ,允许不同源网站对本站进行跨域访问,浏览器就不会对返回的数据进行限制了;
header(‘Access-Control-Allow-Origin: url’) 表示对指定的 url网站不用同源策略
header(‘Access-Control-Allow-Oring: *’) 表示对所有外部网站不用同源策略
- Access-Control-Allow-Origin: http://www.YOURDOMAIN.com
该字段必需。设置允许请求的域名,多个域名以逗号分隔,也可以设置成 * 即允许所有源访问 - Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
该字段必需。设置允许请求的方法,多个方法以逗号分隔 - Access-Control-Allow-Headers: Authorization
该字段可选。设置允许请求自定义的请求头字段,多个字段以逗号分隔 - Access-Control-Allow-Credentials: true
该字段可选。设置是否允许发送 Cookies
2. Jsonp
通常为了减轻web服务器的负载,我们把js、css,img等静态资源分离到另一台独立域名的服务器上,在html页面中再通过相应的标签从不同域名下加载静态资源,而被浏览器允许。即页面中的链接、重定向、表单提交不受同源策略限制。基于此原理,我们可以用 src 和 href 两个属性跨域访问。
例如通过动态创建script,再请求一个带参网址实现跨域通信。
前端原生实现
var script = document.createElement('script');
script.type = 'text/javascript';
// 传参回调函数名 handleCallback 给后端,方便后端返回时执行这个在前端定义的回调函数
script.src = 'http://www.domain2.com:8080/login?user=admin&callback=handleCallback';
document.head.appendChild(script);// 回调执行函数
function handleCallback(res) {console.log('请求成功',res);
}
服务端返回如下(返回时即执行全局 handleCallback 函数):
handleCallback({"status": true, "user": "admin"})
后端 node.js 代码
var querystring = require('querystring');
var http = require('http');
var server = http.createServer();server.on('request', function(req, res) {var params = qs.parse(req.url.split('?')[1]);var fn = params.callback;// jsonp返回设置res.writeHead(200, { 'Content-Type': 'text/javascript' });res.write(fn + '(' + JSON.stringify(params) + ')');res.end();
});server.listen('8080');
console.log('Server is running at port 8080...');
3. nginx代理
跨域原理:同源策略是浏览器的安全策略,不是HTTP协议的一部分。服务器端调用HTTP接口只是使用HTTP协议,不会执行JS脚本,不需要同源策略,也就不存在跨越问题。
实现思路:通过nginx配置一个代理服务器(域名与domain1相同,端口不同)做跳板机,反向代理访问domain2接口,并且可以顺便修改cookie中domain信息,方便当前域cookie写入,实现跨域登录。
nginx配置
// 例如:前端域名 http://localhost:9099 后端域名 http://localhost:9871
server{# 监听9099端口listen 9099;# 域名是localhostserver_name localhost;#凡是localhost:9099/api这个样子的,都转发到真正的服务端地址http://localhost:9871 location ^~ /api {proxy_pass http://localhost:9871; # 反向代理}
}
4. postMessage API
postMessage是HTML5 XMLHttpRequest Level 2中的API,且是为数不多可以跨域操作的window属性之一,它可用于解决以下方面的问题:
a.) 页面和其打开的新窗口的数据传递
b.) 多窗口之间消息传递
c.) 页面与嵌套的iframe消息传递
d.) 上面三个场景的跨域数据传递
postMessage(data,origin)
@params data: html5规范支持任意基本类型或可复制的对象,但部分浏览器只支持字符串,所以传参时最好用JSON.stringify()序列化。
@params origin: 协议+主机+端口号,也可以设置为"*",表示可以传递给任意窗口,如果要指定和当前窗口同源的话设置为"/"。
1. http://www.domain1.com/a.html
<iframe id="iframe" src="http://www.domain2.com/b.html" style="display:none;"></iframe>
<script> var iframe = document.getElementById('iframe');iframe.onload = function() {var data = {name: 'aym'};// 向domain2传送跨域数据iframe.contentWindow.postMessage(JSON.stringify(data), 'http://www.domain2.com');};// 接受domain2返回数据window.addEventListener('message', function(e) {alert('data from domain2 ---> ' + e.data);}, false);
</script>
2. http://www.domain2.com/b.html
<script>// 接收domain1的数据window.addEventListener('message', function(e) {alert('data from domain1 ---> ' + e.data);var data = JSON.parse(e.data);if (data) {data.number = 16;// 处理后再发回domain1window.parent.postMessage(JSON.stringify(data), 'http://www.domain1.com');}}, false);
</script>
Q:常见状态码
1XX:信息性状态码
2XX:成功状态码
200:OK 请求成功,一般用于GET和POST请求
201:Created 已创建,成功请求并创建了新的资源
3XX:重定向状态码
301:Moved Permanently 永久重定向,请求的资源已被分配了新的URL,以后应该使用新的URL去访问该资源
302:Found 临时重定向,请求的资源已被分配了新的URL,希望用户本次使用新的URL
304:Not Modified 未修改
4XX:客户端错误状态码
403:Forbidden 禁止访问,未获得访问权限
404:Not Found 未找到请求的资源
5XX:服务器错误状态码
500:Internal Server Error 服务器内部错误
503:Service Unavailable 服务器超载或系统维护,暂时无法处理请求
Q:创建 Ajax 过程
1. 实例化 XMLHttpRequest 对象
var xhr;
if(window.XMLHttpRequest){// 标准浏览器xhr = new XMLHttpRequest();
}else{// IE浏览器xhr = new ActiveXObject('Mcxml2.XMLHTTP');
}
2. 准备Ajax请求
xhr.open('get', 'url');
3. 发送Ajax请求
xhr.send('data');
4. 服务端接收并处理Ajax请求,返回处理结果(字符串)给客户端
<?phpecho String;print_r String;
?>
5.客户端接收服务端返回的数据
xhr.onreadystatechange = function () {if(xhr.readyState == 4){DOM.innerHTML = xhr.responseText;}
}
Q:浏览器进程和线程
标签页进程
Browser进程(浏览器主进程)
插件进程
GPU进程
Render进程(浏览器内核,即浏览器渲染进程)
- js引擎线程
- GUI渲染线程
- 事件触发线程
- 定时触发器线程
- 异步HTTP请求线程
Q:从输入URL到页面加载发生了什么?
参考视频:https://www.bilibili.com/video/av40168673?from=search&seid=6185720200065621331
一、DNS解析(网址->IP地址)
- 从浏览器中查找DNS缓存
- 如果没有,继续到操作系统中查询DNS缓存
- 如果没有,开始分级查询
3.1 本地DNS服务器
3.2 根域名服务器
3.3 COM顶级域名服务器
3.4 goole.com域名服务器
- 查到IP地址后,继续下一步
二、TCP连接(三次握手)
http超文本传输协议是TCP/IP协议的子集,TCP有6种标示:SYN(建立联机) ACK(确认) PSH(传送) FIN(结束) RST(重置) URG(紧急)
1. 第一次握手:客户端 -> 服务端
- 客户端向服务端发送请求报文,请求建立连接,等待服务端确认。发送字段:
SYN=1(synchronization 同步。请求建立连接)
Seq=x(sequence 客户端序列号)
2. 第二次握手: 服务端 -> 客户端
- 服务端表明收到请求报文并同意建立连接,发送确认报文,询问客户端是否准备好。返回字段:
SYN=1(同意建立连接)
ACK=x+1(acknowledgement 答复。客户端序列号+1)
Seq=y(服务端序列号)
3. 第三次握手:客户端 -> 服务端
- 客户端表明收到确认报文,再返回服务端一个确认报文,表示准备开始发送信息。发送字段:
SYN=0(开始发送信息)
ACK=y+1(服务端序列号+1)
Seq=x+1(序列号设置为服务端ACK)
第一次表明客户端有发送信息的能力
第二次表明服务端有接收信息和发送信息的能力
第三次表明客户端有接收信息的能力
三、 客户端发送HTTP请求
四、服务端处理请求,并返回HTTP报文
五、浏览器解析并渲染页面过程
浏览器解析页面过程:
- 浏览器接收到HTML模板文件,自上而下解析HTML
- 浏览器遇到CSS样式文件表,暂停解析HTML,请求CSS文件
- 服务端返回CSS文件,浏览器开始解析CSS
- 浏览器解析完CSS,继续解析HTML,遇到DOM节点,解析DOM
- 浏览器遇到img图片,异步请求图片,继续解析后面的代码
- 浏览器返回图片,由于图片占有面积影响布局,浏览器重绘
- 浏览器遇到js脚本文件,停止所有文件加载和解析,请求并执行脚本文件(js阻塞,所以js标签尽量放在body最后)
- 浏览器执行完脚本文件,如果后面还有代码,继续解析
- 加载并解析完所有HTML、CSS、JS文件,页面出现
浏览器渲染页面过程:
- 解析HTML,构建DOM树;解析CSS,生成CSS规则
- 构建render树(渲染树,HTML + CSS,不包括display:none)
- 布局render树(layout过程,计算宽高、定位、坐标、换行、positions、overflow、z-index等属性)
4、绘制render树(painting过程,背景 —> 浮动 -> content -> padding -> border)
引起浏览器重新布局layout:
js 修改 DOM 属性或 css 属性,分为两种情况:
1. 重绘,不改变定位、宽高等,只改变元素展示方式
2. 重排/回流,影响文档内容、结构或元素定位
优化:
1. 脱离文档流的重排只影响自己子孙元素
2. 读取element属性会造成重排,尽量避免。如offsetTop/scrollTop/clientTop系列
六、TCP连接结束(四次挥手)
1. 第一次挥手:客户端 -> 服务端
- 客户端发送断开连接的请求
FIN (finish 结束)
ACK=1000 (acknowledgement 答复)
Seq=x (sequence 客户端序列号)
2. 第二次挥手:服务端 -> 客户端
- 服务端接收并同意断开连接的请求
ACK=x+1 (acknowledgement 答复,客户端序列号+1)
Seq=1000 (服务端序列号设置为客户端ACK)
3. 第三次挥手:服务端 -> 客户端
- 服务端发送断开连接的请求
FIN(finish 结束)
ACK=x+1 (客户端序列号+1)
Seq=1000(服务端序列号)
4. 第四次挥手:客户端 -> 服务端
- 客户端断开连接,完成通讯
ACK=1000+1 (服务端序列号+1)
Seq=x+1(客户端序列号设置为服务端ACK)
第一次表明发完了
第二次表明知道发完了
第三次表明收完了
第四次表明知道收完了
Q:JS Event Loop 事件循环
参考视频:https://www.bilibili.com/video/BV1MJ41197Eu?p=36
注:浏览器是多进程、多线程的,JS是单线程的
浏览器每个标签页是一个进程,每个进程里同时有js线程、网络线程、渲染线程等
heap 堆(主要用于内存分配)
- 对象
tack 执行栈/方法调用栈(先进后出)
- 当JS引擎执行函数时,会把函数按照执行顺序放入stack 执行栈,并按照执行完毕的顺序从执行栈里移除。(先进后出)
- 如果一直在调用函数而没有结束(自调用死循环),执行栈容量会达到上限,报错。
task queue 任务队列(异步)
- 如果调用到异步函数,会把异步函数先放入task queue 任务队列,继续执行stack 执行栈里的同步函数。当执行栈的函数全部执行完毕并移除,再把任务队列里的异步函数按照加入任务队列的先后顺序放入执行栈,继续执行。
- JS中用于储存待执行回调函数的队列包含两个不同特定的列队:微队列、宏队列。
microtask 微任务(优先级高)
promise,process.nextTick,Object.obverse,MutationObserver
macrotask 宏任务(优先级低)
定时器,setImmediate,I/O(键盘、网络),UI rending
事件循环过程
- 执行全局 JS 同步代码,有的是同步语句,有的是异步语句(如setTimeout等)。放入 stack 执行栈;
- Event Loop 事件循环 不断检查 stack 执行栈 是否为空;
- 为空时检查 task queue 任务队列(微队列、宏队列) 是否有异步任务, 如果有则开始执行;
- 在本次循环中,取出 microtask queue 微队列 中第一个 microtask 微任务,放入 stack 执行栈 中执行,完成后 microtask queue 微队列 长度减1;
- 继续取出 microtask queue 微队列 中第一个 microtask 微任务,放入 stack 执行栈 中执行,以此类推,直到把 microtask queue 微队列 清空;
注意:如果在执行 microtask 微任务 的过程中,又产生了新的 microtask 微任务 ,会加入到队尾,也在本次循环中执行;
- 取出 macrotask queue 宏队列 中第一个 macrotask 宏任务,放入 stack 执行栈 中执行;
即 所有微任务 microtask + 一个宏任务 macrotask 。(所以多个网络请求可以同时处于等待状态)
- 执行完毕后,调用栈Stack为空;
- 重复 Event Loop 事件循环 (第2-7步)
Q:前端异常监控
基本异常
try {// 正常逻辑
} catch (error) {// 异常处理
}
全局异常
window.onerror = () => {// 异常处理
}window.addEventListener('error', () => {// 异常处理
})
Promise内部异常
window.onunhandledrejection = () => {// 异常处理
}window.addEventListener('unhandledrejection', () => {// 异常处理
})
vue异常
Vue.config.errorHandler = () => {// 异常处理
}
Q:vue生命周期
- beforeCreate:创建前状态
// 例:
beforeCreated () {// 如果localStorage里没有tokenif(!localStorage.getItem('token')){// 编程式导航跳转回登录页面this.$router.push({name:'login';})}
}
- created:创建完毕状态
- beforeMount:挂载前状态
- mounted:挂载结束状态
- beforeUpdate:更新前状态
- updated:更新完状态
- beforeDestroy:销毁前状态
- destroyed:销毁完成状态
Q:Vue Router 导航守卫
导航守卫主要通过跳转或取消的方式守卫导航,有三种方式植入路由导航过程中。
全局守卫
- 全局前置守卫 router.beforeEach((to, from, next) => {})
- 全局后置守卫 router.afterEach ((to, from) => {})
router.js 路由模块
// 实例化路由器,配置路由
const router = new VueRouter({routes:[{path:'/login',component: Login}, {path:'/b',component: comB}]
})
// 拦截路由配置,在所有路由配置生效之前,先执行 beforeEach 方法
router.beforeEach((to, from, next) => {if(to.path === '//login'){next()}else{const token = localStorage.getItem('token');if(!token){router.push({path:'/login'})}else{next(); }}
})
路由独享的守卫
routes:[{path:'/a',component: comA,beforeEnter: (to, from, next) => {}
}]
组件内的守卫
const comA = {template: '\<div>这是路由组件\</div>',beforeRouteEnter (to, from, next) {},beforeRouteUpdate (to, from, next) {},beforeRouteLeave (to, from, next) {}
}
Q:盒模型
盒模型范围:content, padding, border, margin
标准盒模型
盒子的宽高 = content 的宽高
.box {box-sizing: content-box;
}
IE盒模型
盒子的宽高 = content + padding + border 的宽高
.box {box-sizing: border-box;
}
中级前端常见面试题(附答案),持续更新相关推荐
- 「高级java工程师」常见面试题及其答案(持续更新)
「java工程师」常见面试题及其答案请见: 「java工程师」常见面试题及其答案(持续更新)_好人老李的博客-CSDN博客 目录 java基础 常用的 jvm 调优方法? OOM的常见场景及其原因.解 ...
- 「java工程师」常见面试题及其答案(持续更新)
「高级java工程师」常见面试题及其答案: 「高级java工程师」常见面试题及其答案(持续更新)_好人老李的博客-CSDN博客 目录 java基础 面向对象与面向过程的区别? JRE.JDK.JVM的 ...
- 前端常见面试题及答案
文章转自http://www.cnblogs.com/syfwhu/p/4434132.html 前言 本文是在GitHub上看到一个大牛总结的前端常见面试题,很多问题问的都很好,很经典.很有代表性. ...
- 2021最新整理JAVA常见面试题附答案
包含的模块: 本文分为十九个模块,分别是:Java 基础.容器.多线程.反射.对象拷贝.Java Web .异常.网络.设计模式.Spring/Spring MVC.Spring Boot/Sprin ...
- 2022最新整理软件测试常见面试题附答案
包含的模块: 本文分为十九个模块,分别是:软件测试 基础.liunx.MySQL.web测试.接口测试.APP测试 .管理工具.Python.性能测试.selenium.lordrunner.计算机网 ...
- while循环中指针会自动释放吗_C++】C++常见面试题汇总_持续更新中...
1:指针(*).引用(&).解引用(*).取地址(&).的概念和区别 概念: 指针指向一块内存,指针保存的是内存的地址:引用是变量的别名,本质是引用该变量的地址. 解引用是取指针指向的 ...
- 2021年JAVA 精心整理的常见面试题-附详细答案【持续更新~~】
先罗列本篇文章包含的Java 常见面试的主题: 一.Java基础面试题 二.Java 集合框架 三.Linux常用指令 四.MySQL基础面试 多线程与多进程面试 常见设计模式 JVM 底层 关注我们 ...
- 前端面试常见面试题及答案
前端面试常见面试题及答案 h5新特性 ES6新特性 vuex的理解,组成以及原理介绍 前端常用框架 h5新特性 html5总的来说比html4多了十个新特性,但其不支持ie8及ie8以下版本的浏览器 ...
- Spring常见面试题及答案汇总1000道(春招+秋招+社招)
Spring面试题以及答案整理[最新版]Spring高级面试题大全(2021版),发现网上很多Spring面试题都没有答案,所以花了很长时间搜集,本套Spring面试题大全,汇总了大量经典的Sprin ...
最新文章
- 工控安全要避开传统IT安全思路的几个“暗坑”
- import export php,import与export在node.js中的使用方法
- 利用最小二乘法,用直线拟合点时,为什么计算竖直距离而非垂直距离?为什么在线性回归分析中,求的是距离平方和最小,而不是距离之和最小?
- 史上最全 Python Re 模块讲解(二)
- python 单例模式的实现方法_python中单例模式的四种实现方式
- 《C++语言基础》实践参考——友元类
- java8 list 去重_Java8-Stream在集合中的8种应用案例
- MySQL笔记-事务理论及并发存在的三个问题(脏读、不可重复读、幻读)演示
- c语言linux内核开发,Linux 内核源代码的几个C语言技巧
- 基于vue-cli 将webpack3 升级到 webpack4 配置
- docker设置不同网络和迁移到指定网络
- HADOOP高可用机制
- 华为交换机链路聚合使用ENSP模拟器进行实验
- 前端框架Vue(15)——vue-cli 仿网易云音乐 Demo,环境搭建到开发 Vue 全家桶练手项目
- react兼容safari9_解决create-react-app在ie中打开页面空白的兼容性问题
- 智和网管平台SugarNMS政府部门综合网管
- urllib库爬取拍信创意图片(post请求)json传参
- 社工的危害性(一)菜鸟经验_星语惜馨_新浪博客
- Windows相关的DOS命令
- 安信可 ESP8266 12F Flash操作