前端面试题整理(Vue篇)

1.vue中hash和 history的区别

  • 首先最大的区别是带#和不带#的区别
  • hash是利用 onhashchange()方法监听location.hash的改变 ,history是使用pushState()改变url但是不发送请求和replaceState()方法读取浏览器历史栈并对;浏览器历史进行修改。
  • history需要后端的支持 ,每个url地址需要在后端中配置路径 如果找不到的话 就会返回404 ,所以后端资源中得有一个是覆盖所有页面的候选资源 前端得配置一个404页面。

注意: 浏览器输入一个url发生了什么?

2.浏览器输入一个url 后发生了什么?

1.首先解析域名 ,DNS对域名进行解析 ,解析成一个ip地址

2.进行 三次握手

     发送端向接收端发送一个带有SYN的数据包 ,

     接收端收到服务包以后返回给发送端一个SYN /ACK 的数据包 ,

     发送端接收到以后 再返回给接收端一个ACK数据包

3.客户端发送HTTP 请求  带有请求头请求体之类的

4.渲染页面

5. 有可能会四次挥手 有可能是会复用连接

 3.简述一下虚拟dom

虚拟dom是用JavaScript描述的一个dom节点 ,是对dom的一层抽象描述 。

我们每次操作页面的时候如果频繁的操作dom元素会对性能造成影响,所以我们造成抽象dom

 在patch的过程中,尽可能的将差异一次性的更新到dom中,这样dom不会出现性能很差的情况

 他的设计初衷一开始是为了跨平台 ,比如 node就没有虚拟dom ,所以要实现服务端渲染就要借助虚拟dom

 它本身就是JavaScript对象

4. 说一下回流和重绘

重绘:当我们对 DOM 的修改导致了样式的变化、却并未影响其几何属性(比如修改了颜色或背景色)时,

浏览器不需重新计算元素的几何属性、直接为该元素绘制新的样式(跳过了上图所示的回流环节)。

回流:

任何会改变元素几何信息(元素的位置和尺寸大小)的操作,都会触发回流,

当我们对 DOM 的修改引发了 DOM 几何尺寸的变化(比如修改元素的宽、高或隐藏元素等)时,

浏览器需要重新计算元素的几何属性(其他元素的几何属性和位置也会因此受到影响),

然后再将计算的结果绘制出来。这个过程就是回流(也叫重排)

注意:

如何避免回流重绘:

1.尽量少使用style改变样式,使用class来改变样式

2.对于动画尽量放在display:absolute 或者fixed上

3.对于resize 或者 scroll这种要进行 防抖/节流

4.使用display:none,因为在display:none的元素不会触发回流重绘

5.项目中如何将http 换成https

1.我们项目的地址都放在baseUrl字段 只需要更改baseURL中的http 即可

2.可以使用meta改变http

<meta http-equiv ="Content-Security-Policy" content="upgrade-insecure-requests">

6. 说一下diff算法吧

diff 算法是一种通过同层的树节点进行比较的高效算法 ,Diff算法实现的是最小量更新虚拟DOM
其有两个特点:
    比较只会在同层级进行, 不会跨层级比较
    在diff比较的过程中,循环从两边向中间比较
diff 算法的在很多场景下都有应用,在 vue 中,作用于虚拟 dom 渲染成真实 dom 的新旧 VNode 节点比较
原理分析:
    当数据发生改变时,订阅者watcher就会调用patch给真实的DOM打补丁
    通过isSameVnode进行判断,相同则调用patchVnode方法
    patchVnode做了以下操作:
    找到对应的真实dom,称为el
    如果都有都有文本节点且不相等,将el文本节点设置为Vnode的文本节点
    如果oldVnode有子节点而VNode没有,则删除el子节点
    如果oldVnode没有子节点而VNode有,则将VNode的子节点真实化后添加到el
    如果两者都有子节点,则执行updateChildren函数比较子节点
    updateChildren主要做了以下操作:
    设置新旧VNode的头尾指针
    新旧头尾指针进行比较,循环向中间靠拢,根据情况调用patchVnode进行patch重复流程、调用createElem创建一个新节点,从哈希表寻找 key一致的VNode 节点再分情况操作

 7.如何解决1px的问题

1px的问题是 当我们设置 border:1px solid #fff ;时 在某些机型上会显示 2个像素,不会显示 1px;
解决办法:
1.写成0.5px ,但是不推荐,因为兼容性不行,ios支持8以上,安卓不支持 
2.使用伪元素先放大后缩小

#container[data-device="2"] {
    position: relative;
}
#container[data-device="2"]::after{
      position:absolute;
      top: 0;
      left: 0;
      width: 200%;
      height: 200%;
      content:"";
      transform: scale(0.5);
      transform-origin: left top;
      box-sizing: border-box;
      border: 1px solid #333;
    }
}


3.viewport 缩放来解决

const scale = 1 / window.devicePixelRatio;
// 这里 metaEl 指的是 meta 标签对应的 Dom
metaEl.setAttribute('content', `width=device-width,user-scalable=no,initial-scale=${scale},maximum-scale=${scale},minimum-scale=${scale}`);

但是这样会被无差别的缩小

8.封装一个组件需要注意的事情

首先我们要注意一下是UI组件还是业务组件 。在UI组件中我们要注意不能写业务,要将逻辑代码提出来 ,考虑组件的复用性以及通用性。所以我们就要用到组件prop传值。其实就是我们要考虑代码的可读性以及向上向下兼容性。
Vue组件的API主要包含三部分:prop、event、slot
1.prop 是父组件向子组件传值 
但是 prop是单向数据流 要注意不可以在子组件中更改prop传来的值
2.event 是子组件向父组件传递消息的重要途径;
3.slot可以给组件动态插入一些内容或组件,是实现高阶组件的重要途径;当需要多个插槽时,可以使用具名slot

 9.vuex的原理

Vuex仅仅是Vue的一个插件。Vuex只能使用在vue上,因为其高度依赖于Vue的双向绑定和插件系统。
vuex是一个状态管理工具。里面包含 5 种 属性State、 Getter、Mutation 、Action、 Module。
state是一个单一状态树 ,存放了数据 。
Getter类似于Vue的 computed 对象。是根据业务逻辑来处理State,使得生成业务所需的属性。
Mutation是唯一用来更改Vuex中数据的方法 ,使用commit修改state中的数据。
Action是用来解决异步操作而产生的,它提交的是Mutation。
Module是将Vuex模块化的对象,目的是更好的维护。
注意:在刷新网页后,保存在vuex实例store里的数据会丢失 我们可以存放在本地存储中

10.vue中computer和watch有什么区别

1.computer 有缓存 只有当computer依赖的数据改变才会改变 。watch 没有缓存 。
2.computer 不能处理异步请求 ,但是watch可以 。
3.watch监听的数据必须在data或者props中存在 ,而computer是通过计算得到的一个新值。
4.在computer中有两个属性 ,一个是get一个是set,当数据变化时,调用 set 方法。watch监听有两个参数 ,一个是oldValue,一个是newValue