Vue的面试题常识

129 阅读5分钟

1. 什么是 M V VM

概念:他是一种设计模式,Model-View-ViewModel 的模式

image.png 1 Model 层: 数据模型层

通过 Ajaxfetch 等 API 完成客户端和服务端业务模型的同步。

2 View 层: 视图层

作为视图模板存在,其实View 就是⼀个动态模板。

ViewModel 层: 视图模型层

负责暴露数据给 View 层,并对 View 层中的数据绑定声明、 指令声明、 事件绑定声明, 进行实际的业务逻辑实现。

数据变化了, 视图自动更新 => ViewModel 底层会做好监听Object.defineProperty,当数据变化时,View 层会自动更新

视图变化了, 绑定的数据自动更新 => 会监听双向绑定的表单元素的变化,⼀旦变化,绑定的数据也会得到⾃动更新。

2.Vue的声明周期

image.png

4. computed 和 watch的区别是什么?

computed

  1. 它是计算属性。主要用于值的计算并一般会返回一个值。所以它更多⽤于计算值的场景
  2. 它具有缓存性。当访问它来获取值时,它的 getter 函数所计算出来的值会进行缓存
  3. 只有当它依赖的属性值发生了改变,那下⼀次再访问时才会重新调⽤ getter 函数来计算
  4. 它适⽤于计算⽐较消耗性能的计算场景
  5. 必须要有一个返回值

watch

  1. 它更多的是起到 “观察” 的作⽤,类似于对数据进行变化的监听并执行回调。 主要⽤于观察 props 或 本组件data的值,当这些值发生变化时,执⾏处理操作

  2. 不一定要返回某个值

建议

  1. 当目的是进⾏数值计算,且依赖于其他数据,那么推荐使用 computed
  2. 当需要在某个数据发生变化的, 同时做⼀些稍复杂的逻辑操作,那么推荐使⽤ watch

5. Vue双向绑定原理?

在 Vue 2.x 中,利⽤的是 Object.defineProperty 去劫持对象的访问器(Getter、Setter),

当对象属性值发⽣变化时可获取变化,然后根据变化来作后续响应;(一个一个的劫持)

在 Vue 3.0 中,则是通过 Proxy 代理对象进⾏类似的操作。劫持的是整个对象, 只要对象中的属性变化了, 都能劫持到

5.1 Object.defineProperty和Proxy的优缺点?

Proxy

  • 可以直接监听整个对象,⽽⾮是对象的某个属性

  • 可以直接监听数组的变化

  • 拦截⽅法丰富:多达13种,不限于get set deletePropertyhas 等。

    Object.defineProperty 强大很多

Object.defineProperty

  • 兼容性较好(可⽀持到 IE9)
  • 可通过can i use 网站进行查看各浏览器是否兼容支持

6. 如何理解Vue的响应式系统?

Vue的响应式系统基本还是建立与在 M: model数据模型, V:view视图模型, VM: viewModel视图数据模型上

双向绑定的响应式原理还是基于Vue的 MVVM模式设计

  1. 视图变化了, 数据自动更新 => 监听原生的事件即可, 输入框变了, 监听输入框input事件
  2. 数据变化了, 视图要自动更新 => vue2 和 vue3 vue2.0 数据劫持: Object.defineProperty (es5)

vue3.0 数据劫持: Proxy (es6)

总结来说: Vue的双向绑定原理其实就是 MVVM 的基本原理, Vuejs官网已经说明, 实际就是通过 Object.defineProperty方法 完成了对于Vue实例中数据的 劫持, 通过对于 data中数据 进行set的劫持监听, 然后通过**观察者模式**, 通知 对应的绑定节点 进行节点数据更新, 完成数据驱动视图的更新

简单概述 : 通过Object.defineProperty 完成对于数据的劫持, 通过观察者模式, 完成对于节点的数据更新

6.2 观察者模式

观察者模式: 当对象间存在 一对多 关系时,则使用观察者模式(Observer Pattern)。 比如,当一个对象或者数据被修改时,则会自动通知依赖它的对象。

意图: 定义对象间的一种 一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都能得到通知并被自动更新。

Dep要进行 依赖收集,并通过一个subs数组, 记录观察者Watcher,Watcher 分为 渲染 watcher、计算属性 watcher、侦听器 watcher 三种,当数据状态发生改变时,会被 Object.defineProperty 监听劫持到, 会通知到 Dep, 并根据收集的依赖关系,让订阅者Watcher进行数据更新(update)操作 , 派发更新

总结概述: vue采用的是观察者模式, 是一种一对多的关系, 一上来vue在解析渲染时, 会进行依赖收集, 会将渲染 watcher、计算属性 watcher、侦听器 watcher, 都收集到对应的dep中, 将来Object.defineProperty 监听到数据变化, 就根据依赖关系, 派发更新。

用图的方式来看“观察者模式”会清晰很多

image.png

7. 如何处理 打包出来的项目(首屏)加载过慢的问题

SPA应用: 单页应用程序, 所有的功能, 都在一个页面中, 如果第一次将所有的路由资源, 组件都加载了, 就会很慢!

加载过慢 => 一次性加载了过多的资源, 一次性加载了过大的资源

  • 加载过多 => 路由懒加载, 访问到路由, 再加载该路由相关的组件内容
  • 加载过大 => 图片压缩, 文件压缩合并处理, 开启gzip压缩等

比如:

  1. 配置异步组件, 路由懒加载

    const login = () => import('../pages/login.vue')
    
  2. 图片压缩: 使用 webp 格式的图片, 提升首页加载的速度

  3. CDN加速: 配置CDN加速, 加快资源的加载效率 (花钱)

  4. 开启 gzip 压缩 (一般默认服务器开启的, 如果没开, 确实可能会很慢, 可以让后台开一下)