个人介绍,项目经历
1、Vue双向绑定
可以用 v-model 指令在表单及元素上创建双向数据绑定
- 它会根据控件类型自动选取正确的方法来更新元素
- 它负责监听用户的输入事件以更新数据
- v-model总是将 Vue 实例的数据作为数据来源,因此我们应该通过 JavaScript 在组件的data选项中声明初始值
实现原理:v-model只不过是一个语法糖而已,真正的实现靠的还是
- v-bind:绑定响应式数据
- 触发oninput 事件并传递数据
2、Object.definePropety和Proxy区别
在 Vue2.x 的版本中,双向绑定是基于 Object.defineProperty 方式实现的。而 Vue3.x 版本中,使用了 ES6 中的 Proxy 代理的方式实现。
Object.defineProperty(obj, prop, descriptor)
使用 Object.defineProperty 会产生三个主要的问题:
- 不能监听数组的变化
在 Vue2.x 中解决数组监听的方法是将能够改变原数组的方法进行重写实现(比如:push、 pop、shift、unshift、splice、sort、reverse),举例:
1// 我们重写 push 方法
2const originalPush = Array.prototype.push
3
4Array.prototype.push = function() {
5 // 我们在这个位置就可以进行 数据劫持 了
6 console.log('数组被改变了')
7
8 originalPush.apply(this, arguments)
9}
- 必须遍历对象的每个属性
可以通过 Object.keys() 来实现
- 必须深层遍历嵌套的对象
通过递归深层遍历嵌套对象,然后通过 Object.keys() 来实现对每个属性的劫持
Proxy
- Proxy 针对的整个对象,Object.defineProperty 针对单个属性,这就解决了需要对对象进行深度递归实现对每个属性劫持的问题
- Proxy 解决了 Object.defineProperty 无法劫持数组的问题
3、v-if和v-show区别
vue 中 v-show 与 v-if 的作用效果是相同的,都能控制元素在页面是否显示
- 当表达式为
true的时候,都会占据页面的位置 - 当表达式都为
false时,都不会占据页面位置
控制手段:v-show隐藏则是为该元素添加css--display:none,dom元素依旧还在。v-if显示隐藏是将dom元素整个添加或删除
编译过程:v-if切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件;v-show只是简单的基于css切换
v-show由false变为true的时候不会触发组件的生命周期v-if由false变为true的时候,触发组件的beforeCreate、create、beforeMount、mounted钩子,由true变为false的时候触发组件的beforeDestory、destoryed方法
4、HTTPS和HTTP区别
HTTPS是在HTTP的基础上加入了SSL协议,SSL依靠证书来验证服务器的身份,并为浏览器和服务器之间的通信加密(在传输层)
HTTP + 加密 + 认证 + 完整性保护 = HTTPS
-
HTTPS协议需要到CA申请证书或自制证书 -
HTTP的信息是明文传输;HTTPS则是具有安全性的ssl加密 -
HTTP是直接与TCP进行数据传输; 而HTTPS运行在SSL/TLS(安全传输层协议)之上,SSL/TLS运行在TCP之上,用的端口也不一样,前者是80(需要国内备案),后者是443 -
HTTP的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的,可进行加密传输、身份认证的网络协议,比HTTP协议安全
5、三次握手
TCP是面向连接的,三次握手就是用来建立连接的,四次握手就是用来断开连接的。
我们来看一下三次握手的过程:
-
1、客户端主动发出请求,SYN标志位为1,表示要建立TCP连接,同时seq=x,表示告诉服务器我的数据会从x的序列号开始往后面发。
-
2、服务端确认请求,SYN标志位为1,表示建立TCP连接,ACK=1表示收到了连接请求并确认,同时seq=y,表示告诉客户端我的数据会从y的序列号开始往后面发,ack=x+1,即告诉客户端你发的数据我收到了,你下一次发送的序列号应该是x+1。
-
3、客户端确认回复,ACK=1表示收到了连接请求并确认,同时seq=x+1,表示之前的序列号+ 1,ack=y+1,即告诉服务端你发的数据我收到了,你下一次发送的序列号应该是y+1。
6、cache-control
7、localStorage和sessionStorage
共同点:统称webStorage 都是实现本地存储机制,保存在浏览器端、且同源的 都有四个API:setItem(存储)、getItem(读取)、removeItem(清除)、clear(清空)
区别:
- cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递,而sessionStorage和localStorage不会自动把数据发送给服务器,仅在本地保存。cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下
- 存储大小限制也不同,cookie数据不能超过4K,同时因为每次http请求都会携带cookie、所以cookie只适合保存很小的数据,如会话标识。sessionStorage和localStorage虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大
- 数据有效期不同,sessionStorage:仅在当前浏览器窗口关闭之前有效;localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;cookie:只在设置的cookie过期时间之前有效,即使窗口关闭或浏览器关闭
- 作用域不同,sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;localstorage在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的
8、vue组件通信
- 父子关系的组件数据传递选择
props与$emit进行传递,也可选择ref -
- 适用场景:父组件传递数据给子组件
-
- 子组件设置
props属性,定义接收父组件传递过来的参数
- 子组件设置
-
- 父组件在使用子组件标签中通过字面量来传递值
- 兄弟关系的组件数据传递可选择
$bus,其次可以选择$parent进行传递 -
- 使用场景:兄弟组件传值
-
- 创建一个中央时间总线
EventBus
- 创建一个中央时间总线
-
- 兄弟组件通过
$emit触发自定义事件,$emit第二个参数为传递的数值
- 兄弟组件通过
-
- 另一个兄弟组件通过
$on监听自定义事件
- 另一个兄弟组件通过
- 祖先与后代组件数据传递可选择
attrs与listeners或者Provide与Inject -
- 在祖先组件定义
provide属性,返回传递的值
- 在祖先组件定义
-
- 在后代组件通过
inject接收组件传递过来的值
- 在后代组件通过
- 复杂关系的组件数据传递可以通过
vuex存放共享的变量
13、vue生命周期
Vue实例从创建到销毁的过程就是生命周期,即指从创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、卸载等一系列过程
ue生命周期总共可以分为8个阶段:创建前后, 载入前后,更新前后,销毁前销毁后,以及一些特殊场景的生命周期
| 生命周期 | 描述 |
|---|---|
| beforeCreate | 组件实例被创建之初 |
| created | 组件实例已经完全创建 |
| beforeMount | 组件挂载之前 |
| mounted | 组件挂载到实例上去之后 |
| beforeUpdate | 组件数据发生变化,更新之前 |
| updated | 数据数据更新之后 |
| beforeDestroy | 组件实例销毁之前 |
| destroyed | 组件实例销毁之后 |
| activated | keep-alive 缓存的组件激活时 |
| deactivated | keep-alive 缓存的组件停用时调用 |
| errorCaptured | 捕获一个来自子孙组件的错误时被调用 |
| 生命周期 | 描述 |
| ------------- | ------------------------------ |
| beforeCreate | 执行时组件实例还未创建,通常用于插件开发中执行一些初始化任务 |
| created | 组件初始化完毕,各种数据可以使用,常用于异步数据获取 |
| beforeMount | 未执行渲染、更新,dom未创建 |
| mounted | 初始化结束,dom已创建,可用于获取访问数据和dom元素 |
| beforeUpdate | 更新前,可用于获取更新前各种状态 |
| updated | 更新后,所有状态已是最新 |
| beforeDestroy | 销毁前,可用于一些定时器或订阅的取消 |
| destroyed | 组件已销毁,作用同上 |
9、怎么判断数据类型
-
使用
typeof进行判断语法:
typeof 判断的数据
特点:可以准确判断基本数据类型,无法对复杂数据类型进行准确判断 -
使用
constructor进行判断语法:
对象名.constructor
特点:只能判断复杂数据类型,不能判断基本数据类型 -
使用
instanceof进行判断语法:
对象名 instanceof 构造函数
特点:只能判断复杂数据类型,不能判断基本数据类型 -
使用
Object.prototype.toString.call()判断语法:Object.prototype.toString.call(需要判断的数据)
特点:可以准确判断所有数据类型
10、组件化编码流程
1、按照功能点拆分静态组件 2、实现动态组件,考虑数据的存放位置,一个组件在用就放在组件身上,如果是多个组件共同使用,就放在他们的父组件身上(状态提升)。 3、实现交互:从绑定事件开始
11、flex属性
容器属性有:
- flex-direction:决定主轴的方向(即项目的排列方向)
- flex-wrap:决定容器内项目是否可换行
- flex-flow:默认值为
row nowrap水平不换行 - justify-content:定义了项目在主轴上的对齐方式
- align-items:定义项目在交叉轴上如何对齐
- align-content:定义了多根轴线的对齐方式。
flex属性是flex-grow, flex-shrink 和 flex-basis的简写
- flex: 1 相当于flex-grow:1,父元素设置display:flex属性,固定侧边栏,子元素设置flex:1会自动填充剩余空间
12、js的事件循环机制
为了解决js单线程运行阻塞问题,引入事件循环的运行机制。同步任务进入主线程,异步任务进入任务队列,主线程内的任务执行完毕为空,会去任务队列读取对应的任务,推入主线程执行,上述过程的不断重复就是事件循环。
13、不能使用箭头函数的情况
1.不应该使用箭头函数来定义一个生命周期方法
2.不应该使用箭头函数来定义method函数
3.不应该使用箭头函数来定义计算属性函数
4.不应该对 data 属性使用箭头函数
5.不应该使用箭头函数来定义 watcher 函数
原因: 箭头函数绑定了父级作用域的上下文,this 将不会按照期望指向 Vue 实例。不能使用this来访问你组件中的data数据以及method方法了。this将会指向undefined。
14、虚拟DOM
创建虚拟DOM就是为了更好将虚拟的节点渲染到页面视图中,所以虚拟DOM对象的节点与真实DOM的属性一一照应,虚拟 DOM 最大的优势在于抽象了原本的渲染过程,实现了跨平台的能力。
15、深拷贝和浅拷贝
浅拷贝是创建新的数据,这个数据有着原始数据属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值。如果属性是引用类型,拷贝的就是内存地址。
深拷贝是开辟一个新的栈,两个对象属完成相同,但是对应两个不同的地址,修改一个对象的属性,不会改变另一个对象的属性。
常见的深拷贝方式有:
- _.cloneDeep()
- jQuery.extend()
- JSON.stringify()
- 手写循环递归