面试官您好,我叫。。。,19年毕业于。。。。大学。。。专业,毕业后就从事了前端开发相关的工作,并且今年在工作之余拿到了国际PMP证书,成绩是5A。我平常吃苦耐劳、善于总结、拥有自主学习新知识的能力,热爱钻研技术上的问题。并且看好互联网行业,并打算长期在 IT 行业发展。
加载渲染过程
父beforeCreate —> 父created —> 父beforeMount —> 子beforeCreate —> 子created —> 子beforeMount —> 子mounted —> 父mounted
子组件更新过程
父beforeUpdate —> 子beforeUpdate —> 子updated —> 父updated
父组件更新过程
父beforeUpdate —> 父updated
销毁过程
父beforeDestroy —> 子beforeDestroy —> 子destroyed —> 父destroyed
一、编码优化:
1.不要将所有的数据都放在data中,data中的数据都会增加getter和setter,会收集对应的 watcher,这样就会降低性能。
vue 在 v-for 时给每项元素绑定事件需要用事件代理,节约性能。
单页面采用keep-alive缓存组件。
4.尽可能拆分组件,来提高复用性、增加代码的可维护性,减少不必要的渲染。因为组件粒度最细,改组件的数组,它只会渲染当前的组件。
v-if 当值为false时内部指令不会执行,具有阻断功能,很多情况下使用v-if替代v-show,合理使用if和show。
key 保证唯一性,不要使用索引 ( vue 中diff算法会采用就地复用策略)。
data中的所以数据都会被劫持,所以将数据尽可能扁平化,如果数据只是用来渲染可以使用Object.freeze,可以将数据冻结起来,这样就不会增加getter和setter。
8.合理使用路由懒加载、异步组件。
9.尽量采用runtime运行时版本。
10.数据持久化的问题,使用防抖、节流进行优化,尽可能的少执行和不执行。
二、加载性能:
1.使用第三方插件实现按需加载( babel-plugin-component )
2.滚动到可视区域动态加载 ( https://tangbc.github.io/vue-virtual-scroll-list )
3.图片懒加载 (https://github.com/hilongjw/vue-lazyload.git)
三、用户体验:
1.app-skeleton 骨架屏
2.app-shell app壳
3.pwa 可以实现H5的离线缓存,使用servicewor
四、SEO 优化:
1.预渲染插件 prerender-spa-plugin,可以把我们代码提前运行起来,最后将代码保存下来,缺陷就是不实时。
2.服务端渲染 ssr
五、.打包优化:
1.使用 cdn 的方式加载第三方模块
2.多线程打包 happypack
3.抽离公共文件 splitChunks
4.sourceMap 生成
六、缓存和压缩:
1.客户端缓存、服务端缓存
2.服务端 gzip 压缩
onhashchange
history.pushState
20Kb => 10Kb
)Object.defineProperty => Proxy
)Virtual DOM
重构,提供diff
算法效率Options API => Function_Based API
)1xx:指示信息–表示请求已接收,继续处理
2xx:成功–表示请求已被成功接收、理解、接受
3xx:重定向–要完成请求必须进行更进一步的操作
4xx:客户端错误–请求有语法错误或请求无法实现
5xx:服务器端错误–服务器未能实现合法的请求
200:请求被正常处理
400:**请求报文语法有误,服务器无法识别
**401:**请求需要认证
**403:**禁止被访问
**404:**服务器无法找到对应资源
**500:服务器内部错误
503:服务器正忙
每个对象都有一个内部属性 prototype,我们通常称之为原型.
原型的值可以是一个对象,也可以是null.
如果它的值是一个对象,则这个对象也一定有自己的原型.
这样就形成了一条线性的链,我们称之为原型链.
访问一个对象的原型可以使用Object.getPrototypeOf方法,或者__proto__属性.
原型向上查找的过程属于原型链;
特点
什么是 Promise
Promise 是异步编程的一种解决方案,比传统的异步解决方案【回调函数】和【事件】更合理、更强大。
promise有几种状态
promise有三种状态,分别为pending(等待中)、fulfilled(已成功)、rejected(已失败)
三个状态之间的变化,通过resolve将promise的状态从pending变成fulfilled,调用reject将promise的状态从pending变成rejected。
async、await
将异步强行转换为同步处理。
async/await是寄生于Promise,Generater的语法糖。
规则:
1 async和await是配对使用的,await存在于async的内部。否则会报错
2 await表示在这里等待一个promise返回,再接下来执行
3 await后面跟着的应该是一个promise对象,(也可以不是,如果不是接下来也没什么意义了…)
宏任务
宏任务指执行栈中待执行的任务,计时器,事件回调,http回调都是宏任务。
微任务
微任务指执行栈清空后立即执行的任务(VIP通道,贵族就是不一样~),Promise 和 MutationObserver都是微任务。
微任务的优先级高于宏任务
(1)用了箭头函数,this就不是指向window,而是父级(指向是可变的)
【普通函数this指向直接调用者】
(2)不能够使用arguments对象
(3)不能用作构造函数,这就是说不能够使用new命令,否则会抛出一个错误
(4)不可以使用yield命令,因此箭头函数不能用作 Generator 函数
变异方法
方法名 | 用法 | 返回值 |
---|---|---|
sort() | 默认按字符串编码的顺序排列,非string会自动转换成string | 排序后的数组 |
reverse() | 将数组元素倒序排列 | 倒序的数组 |
push() | (入栈)向数组末尾添加一个或多个元素 | 新数组的长度 |
pop() | (出栈)删除数组的最后一个元素 | 删除的元素 |
unshift() | 向数组开头添加一个或多个元素 | 新数组的长度 |
shift() | 删除数组的第一个元素 | 删除的元素 |
splice() | 从数组中删除项目(start,howmany) | 删除的项目 |
非变异方法
方法名 | 用法 | 返回值 |
---|---|---|
join() | 将数组拼接为字符串(括号内可自定义分隔符,默认为逗号) | 字符串 |
concat() | 将多个数组拼接成一个数组 | 拼接后的数组 |
slice() | 从已有数组中返回选定的元素[start,end) | 选中的元素数组 |
toString() | 将数组转换为字符串 | 字符串 |
valueOf() | 返回数组对象本身 | 数组对象本身 |
方法名 | 用法 |
---|---|
charAt(index) | 返回指定索引位置的字符 |
charCodeAt(index) | 返回指定索引位置的字符编码 |
indexOf(str,index) | 返回index后,首次出现的位置 |
lastIndexOf(str,index) | 返回index前,末次出现的位置 |
toLowerCase()/toUpperCase | 转为大写/转为小写 |
substr(start,howmany) | 从已有字符串中截取字符串 |
substring/slice(start,stop)[stop可省略,直接到最后一位] | 从已有字符串中截取字符串 |
split(分隔符,限制数组长度) | 将字符串根据分隔符分割为字符串数组 |
0:请求未初始化
1:服务器连接已建立
2:请求已接收
3:请求处理中
4:请求已完成,且响应已就绪
200 请求成功
301 资源(网页等)被永久转移到其他URL
404 请求的资源(网页等)不存在
500 服务器内部错误
(1)发起get请求
const xhr=new XMLHttpRequest();
xhr.open('get','/users',true); //传参 xhr.open('get','/users?name=jack&age=19',true)
xhr.onreadystatechange=function(){
if(xhr.readyState===4){
if(xhr.status===200){
return xhr.responseText;
}else{
return 'error';
}
}
};
xhr.send();
(2)发起post请求
const xhr=new XMLHttpRequest();
xhr.open('post','/users',true);
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xhr.onreadystatechange=function(){
if(xhr.readyState===4){
if(xhr.status===200){
return (JSON.parse(xhr.responseText));
}else{
return 'error';
}
}
};
xhr.send('name=jack&age=19');
postMsg() {
let iframe = document.getElementById("map");//获取到iframe
iframe.contentWindow.postMessage( //使用postMessage进行跨域传输
{ //所需传输的数据(具体参数见下表)
data: {
cmd: "calcPath",
data: {}
}
},
"*"
);
}
window.addEventListener("message", function(e) {
if (e.origin === "https://fljs.jchc.cn:8888") {
console.log(e.data.message);//如有数据不正确会在此处报错
}
});