参考博客 >>
Vue
1、React / Vue.js 之类的框架为什么须要给组件增加 key 属性,其作用是什么?
[高频]
key 相当于每个节点的 id,在 render 函数执行时,会生成虚构节点, 在数据变动的时候,virtual dom 将新的虚构节点的 key 去比照旧的虚构节点数组的 key, 从而精确找到须要更新的旧节点,将虚构节点映射到视图上。没有 key 的话,会采纳遍历的办法找到对应的旧节点,一种是利用 key 的唯一性生成 map 对象(map 映射),一种是遍历查找,相比而言,map 映射速度更快。(在大量频繁的数据更新下,virtual dom 可能对视图进行正当高效的更新)
2、Vue 数据响应式
[高频]
Vue 初始化过程中,data 通过 observer 转换成 getter/setter 的模式,在 render 函数执行时,会去读取所需对象的值,会触发 Object.defineProperty.get 办法,实例化 Dep 将 watcher 的订阅操作增加到 subs 进行依赖收集,数据变动时,会触发 Object.defineProperty.set 办法,外面调用 dep.notify(),而后循环调用所有的 watcher.update 办法,通过 watcher 执行 render 函数,从而把数据插入到 root 节点
3、Vue watch 和 computed 的区别
[高频]
computed 由 get 和 set 组成,默认只有 get, 监听的是依赖值,变动的时候从新计算并动静返回内容,相干依赖没有扭转的状况下,拜访的都是缓存的计算结果,只能同步执行
watch 监听的是属性值,当属性值发生变化去触发回调,实现一段简单的业务逻辑,能够执行异步操作。也能够监听 computed 属性。监听简单类型 -deep:true。
4、Vue 组件通信形式
[高频]
父子 props/$emit:父组件 A 通过 props 向子组件 B 传递数据,子组件 $emit 向父组件发送音讯, 父组件 v -on 接管
父子 $parent/$children 与 ref:这两种都是间接失去组件实例,应用后能够间接调用组件的办法或拜访数据
多级 vuex (实用于中大型单页利用):
对 vue 多个组件的共享状态集中管理,实现了一个单向数据流,领有一个 state 容器存放数据,通过 commit 触发 mutation 来更改 state,mutation 只能进行同步操作,且办法名是惟一的,所有的异步操作或者批量同步操作都要走 action,反对多个同名办法,通过 dispatch 来触发,而后通过 commit 触发 mutation,间接更新 state。getters 就相当于对数据的一个过滤和加工,像计算属性一样,getter 的返回值会依据它的依赖被缓存起来,且只有当它的依赖值产生了扭转才会被从新计算。
vuex 存储的数据是响应式的,然而并不会保留,在刷新后会回到初始状态,能够在数据发生变化的时候存储一份到 localstorage,在页面刷新后,如果 locastorage 里有寄存的数据,就能够取出来替换 store 里的 state
多级 $emit/$on:通过一个空的 Vue 实例作为地方事件总线,$emie 触发事件,$on 监听事件
多级 $attrs/$listeners(实用于仅仅传递数据,不做两头解决):蕴含父作用域中绑定的非 props 属性,通过 v - bind=”$attrs” 传入外部组件 / 蕴含父组件中不含.native 润饰的非原生事件,通过 v -on=”$listeners” 传入外部组件
多级 provide/inject(实用于子组件获取下级组件状态):跨级组件建设了一种被动提供和依赖注入的关系,通过 provide 提供变量,通过 inject 注入变量
5、vuex 和 localStorage 的区别
[中高频]
- 1. 本质区别
vuex 存的是状态,存储在内存;localStorage 是浏览器提供的接口,让你存的是接口,以文件的模式存储到本地
2. 利用场景
vuex 用于组件之间的传值,localStorage 则次要用于页面之间的传值
3. 永久性
当刷新页面时,vuex 存储的值会失落,localStorage 不会
总结
localStorage 能够代替 vuex,对于不变的数据的确能够,然而当两个组件独特用以数据源,如果其中一个组件中的数据源扭转,心愿另一个组件响应变动,这时候就要抉择用 vuex。vuex 是 vue 的状态管理机制,是不便组件之间通信的。一个组件的数据变动是会映射到应用这个数据的其余组件。而 localStorage 是本地存储,是将数据存储到浏览器的办法,个别在跨页面时应用。
6、Vue 路由传参
[低低频]
- 用 name 传递参数:$route.name
- 通过 <router-link> 标签中的 to 传参:$route.params
- 利用 url 传递参数:$route.params
- 通过 path 来匹配路由,而后通过 query 来传递参数:$route.query
7、Vue3.0
[低频]
- Proxy,它容许框架拦挡针对对象(属性)的操作;
- 切换到 TypeScript 将容许咱们主动生成申明文件,从而加重保护累赘;
- 将大多数全局 API 和外部帮忙程序挪动到 Javascript 的 module.exports 属性上,只有在模板中理论应用某个个性时,该代码才导入该个性的帮忙程序;
- Composition API,容许用户像编写函数一样自在地表白、组合和重用有状态的组件逻辑,
8、keep-alive
[没问]
- 使组件保留状态,防止被从新渲染。
- 当组件被激活时,触发钩子函数 activated,当组件被移除时,触发钩子函数 deactivated。
9、组件中 data 为什么是一个函数
[低频]
- 组件是用来复用的,data 是函数的话,能够使每个组件保护返回对象的独立拷贝,组件之间的 data 不会相互影响
10、scoped 原理
[低频]
给 HTML 的 DOM 节点加一个不反复属性 data-v-469af010 标记唯一性
11、vue 兼容 ie
[低频]
- 应用 babel-polyfill 插件,将 es6 转换为 es5。
- vue 不反对 ie8 及以下,换框架,或者提醒用户降级浏览器。微软在 2016 年已进行对 ie8/9/10 的技术支持,安全性得不到保障。
12、跨域
[中频]
- nginx 代理
JS
1、运行机制
[中频]
js 引擎在解释和执行 js 代码时的线程只有一个主线程,所有的同步工作在主线程中执行过程中,会造成执行栈。settimeout 这类的办法浏览器默认为耗时程序,会将其放入工作队列中,一旦执行栈中所有同步工作执行完结,零碎就会读取工作队列,如果有待处理事件就取出相干事件和回调函数放入执行栈中执行,主线程会反复从工作队列中读取工作、执行工作,这种机制叫事件循环。
2、闭包
[低频]
简略来说,就是一个函数外部的函数,能够拜访内部函数的局部变量
作用:
- 能够读取函数外部的变量,
- 能够使变量的值长期保留在内存中
- 能够用来实现 JS 模块
- 闭包应用完了后,要立刻开释资源,将援用变量指向 null。
3、原型链
[低频]
每个函数数据类型都会自带一个 prototype 属性,这个属性指向了函数的原型对象,原型对象就像一个公共区域,同一个类的所有实例都能够拜访到;
每个对象数据类型会自带一个_proto_属性,这个属性指向实例的构造函数的原型;
比方当拜访一个实例对象的属性或者办法时,对象本身找不到的时候,会通过对象的_proto_,也就是对象的构造函数的 prototype 去找,还找不到就去原型的原型上找,始终到 Object 为止。Object 是 js 所有对象数据类型的基类,它的原型上没有_proto_属性;
4、判断数据类型
[低频]
- typeof A- 不能判断 null、Array 等
- -A instanceof B- A 是否为 B 的实例,不能判断 null、undefined
- A.constructor- 和 instanceof 相似,能够解决根本数据类型,函数的 constructor 不稳固,会笼罩之前的 constructor
- Object.prototype.toString.call- 最精确罕用
5、模块化
[没问]
- CommonJs- 输出的是值的拷贝,在运行时加载
- ES6 模块 - 输出的是值的援用,在编译时输入接口
- 第一个差别 -CommonJs 一旦输入一个值,模块外部的变动不会影响到这个值,ES6 模块是动静援用,模块里的变量绑定了其所在模块,不会缓存值
- 第二个差别 -CommonJs 加载的是一个对象,在脚本运行完才会生成,ES6 模块的对外接口是一种动态定义,在代码动态解析的时候就会生成
6、ES6
[高频]
- 箭头函数:缩减代码;扭转 this 指向 - 指向函数应用时所在的作用域,而不是定义时所在作用域;
- 块级作用域:避免内层变量笼罩外层变量;防止变量泄露,成为全局变量;
- 数组的扩大:find()、findIndex()- 用于找出第一个符合条件的数组成员 / 下标;includes()- 示意某个数组是否蕴含给定的值;
- 扩大运算符:将数组宰割,并将各个项作为拆散的参数传给函数;
- 模板字符串
- Promise
- 模块化
7、深浅拷贝
[中频]
浅拷贝:只遍历一层
- Object.assign()- 连贯对象
var obj = {a:{name:"kaiqin",age:19}};
var obj1 = Object.assign({},obj,obj2);
- concat、slice、扩大运算符
深拷贝:- 只实用于纯数据 json 对象的深度克隆 -JSON.parse(JSON.stringify(obj))
会把函数或 undefined 失落
obj 外面有工夫对象,工夫将只是字符串的模式。而不是工夫对象;- $.extend - 为 true 为深拷贝,为 false,则为浅拷贝
let a=[0,1,[2,3],4],
b=$.extend(true,[],a);
8、promise 和 async await
[中频]
- promise
let p = new Promise((resolve,reject) => {
//...
resolve('success')
});
p.then(result => {console.log(result);//success
});
- async
async function demo() {let result = await Promise.resolve(123);
console.log(result);
}
demo();
- 在错误处理方面,async 函数更容易捕捉异样谬误
9、不借助 v -model 实现双向绑定
[低频]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<input type="text" id="ip">
<span id="sb"></span>
<script>
// 数据劫持
var obj = {};
Object.defineProperty(obj,'hello',{set: function(newValue){document.getElementById('ip').value = newValue
document.getElementById('sb').innerHTML = newValue
}
});
document.addEventListener('keyup',function(e){obj.hello = e.target.value // 监听事件 批改 hello 的值, 触发 set 函数 执行 set 函数内的内容})
</script>
</body>
</html>
10、防抖和节流
[低频]
- 防抖和节流的作用都是避免函数屡次调用。区别在于,假如一个用户始终触发这个函数,且每次触发函数的距离小于 wait,防抖的状况下 只会调用一次 ,而节流的状况会 每隔肯定工夫(参数 wait)调用函数。
- 防抖(debounce)
search 搜寻联想,用户在一直输出值时,用防抖来节约申请资源。
window 触发 resize 的时候,一直的调整浏览器窗口大小会一直的触发这个事件,用防抖来让其只触发一次
- 节流(throttle)
鼠标一直点击触发,mousedown(单位工夫内只触发一次)
监听滚动事件,比方是否滑到底部主动加载更多,用 throttle 来判断
### 浏览器
[没问]
1、HTTP
- 申请行
- 申请头:Accept- 通知服务端,客户端接管什么类型的响应,Accept-Encoding- 接管什么类型的编码和压缩模式
- 响应头:Access-Control-Allow-Origin- 指定哪些站点能够参加跨站资源共享,Date- 音讯发送的日期和工夫
- 共有:Cache-Control,Connection-keeplive 长久连贯,一个连贯能够发多个申请,content-type- 设置申请体的类型,Content-Length- 设置申请体的字节长度。
- 状态码:
1xx- 提示信息 - 申请已接管,持续解决
2xx- 胜利 - 申请已胜利接管、了解
3xx- 重定向 - 在实现申请前必须做进一步操作
4xx- 客户端谬误 -
5xx- 服务端谬误
403: 禁止拜访申请页面;404: 申请资源不存在
2、存储
[中高频]
- Cookie- 个别由服务器生成,携带在 Http 申请头中,能够设置生效工夫;若在浏览器端生成,默认是在浏览器敞开后生效
主要参数有:
(1)expires 过期工夫
(2)path cookie 寄存门路
(3)domain 可拜访该 Cookie 的域名
(4)Set-Cookie: name value
- localStorage- 永恒保留,生效须要被动革除
- sessionStorage- 存储在以后会话中,敞开标签或浏览器会生效
3、从 URL 输出到页面展示到底产生什么
[没问]
- 输出 URL 后,浏览器会向 DNS 服务器发送域名,DNS 服务器会返回和域名统一的 IP;
- 浏览器向服务器发送申请前会进行 TCP 三次握手;
- 完结后发送 HTTP 申请报文,服务器解决并返回 HTTP 响应报文;
- 浏览器拿到响应内容后,依据 HTML 解析出 DOM 树,依据 CSS 解析出 CSS 规定树,联合 DOM 树和 CSS 规定树解析出渲染树,依据渲染树计算每个节点的信息,依据计算信息绘制页面;
- 数据传送结束,会断开 TCP 连贯,发动四次挥手
三次握手
- 浏览器通知服务器,我要发送申请了;
- 服务器通知浏览器,我筹备接管了,你连忙发吧;
- 浏览器通知服务器,我马上就发了,筹备接管吧
四次挥手
- 浏览器通知服务器,我申请报文发送完了,你筹备敞开吧;
- 服务器通知浏览器,我申请报文接管完了,我筹备敞开了,你也筹备吧;
- 服务器通知浏览器,我响应报文发送完了,我筹备敞开了,你也筹备吧;
- 浏览器通知服务器,我响应报文接管完了,我筹备敞开了,你也筹备吧;
布局
响应式布局
[中高频]
- 百分比 - 实用于挪动端和 PC 端专用一套代码
- 媒体查问 - 利用特定的款式
- rem- 实用于挪动端 -document.documentElement.style.fontSize=(屏幕宽度 / 设计稿宽度)*100+”px”;绝对于 html 根元素的字体尺寸
em- 绝对于以后行内文本的字体尺寸,会继承父级元素的字体尺寸
CSS
革除浮动
[中频]
- 给父元素增加 after 伪元素,实现元素开端增加一个看不见的块元素革除浮动
- overflow:hidden- 触发 BFC 原理
-br 标签 增加 clear=”all”
程度居中
[中频]
- text-align:center;
- margin:0 atuo
- display:flex,align-item:center;
程度垂直居中
[中高频]
- position: absolute;;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto; - position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%); - display: flex;
justify-content: center;
align-items: center;
左侧固定右侧自适应;
[低频]
- 左侧 float: left; 右侧 margin-left
- 左侧 flex:0 0 200px; 右侧 flex:1
box-sizing
[中高频]
- content-box
- border-box- 宽高不蕴含 padding/margin/border
Less
[没问]
- @变量存储专用的款式、门路、选择器等
- 混合应用,引入一个类到另一个类,应用 extend 伪类来实现款式的继承
- & 嵌套
- 函数 & 运算
- 命名空间和作用域
### 优化
压缩代码:
[高频]
- 路由懒加载
- vue 我的项目和部署 nginx 同时开启 Gzip
- 将公共依赖库挂到 CDN 上,通过 script 引入
- 第三方插件的按需引入
- 图片压缩并上传到云服务器
- 浏览器缓存
查看打包大小
- 剖析工具 webpack-bundle-analyzer
Webpack 优化
构建速度优化
代码品质压缩
其余
Git:回滚
[低频]
- checkout – 未执行 git add,舍弃以后所有改变
- reset – 重置缓存区
- revert – 撤销曾经公布到仓库的提交
MVVM 和 MVC
[中频]
- 把 Model 和 View 关联起来的就是 ViewModel。ViewModel 负责把 Model 的数据同步到 View 显示进去,还负责把 View 的批改同步回 Model
- 每一层互相独立,变更数据不必批改其余层
前端工程化当初的长处
[低频]
- 规范化 - 编码标准、目录构造的制订、前后端接口标准
- 模块化 -JS 的模块化、css 的模块化、资源的模块化
- 组件化 - 每个蕴含模板 (HTML)+ 款式(CSS)+ 逻辑(JS) 性能齐备的结构单元
- 自动化 - 构建、部署、测试
- 组件化≠模块化。模块化只是在文件层面上,对代码或资源的拆分;而组件化是在设计层面上,对 UI(用户界面)的拆分。