1. 什么是 M V VM
概念:他是一种设计模式,Model-View-ViewModel 的模式
1 Model 层: 数据模型层
通过 Ajax、fetch 等 API 完成客户端和服务端业务模型的同步。
2 View 层: 视图层
作为视图模板存在,其实View 就是⼀个动态模板。
ViewModel 层: 视图模型层
负责暴露数据给 View 层,并对 View 层中的数据绑定声明、 指令声明、 事件绑定声明, 进行实际的业务逻辑实现。
数据变化了, 视图自动更新 => ViewModel 底层会做好监听Object.defineProperty,当数据变化时,View 层会自动更新
视图变化了, 绑定的数据自动更新 => 会监听双向绑定的表单元素的变化,⼀旦变化,绑定的数据也会得到⾃动更新。
2.Vue的声明周期
4. computed 和 watch的区别是什么?
computed
- 它是计算属性。主要用于值的计算并一般会返回一个值。所以它更多⽤于计算值的场景
- 它具有缓存性。当访问它来获取值时,它的 getter 函数所计算出来的值会进行缓存
- 只有当它依赖的属性值发生了改变,那下⼀次再访问时才会重新调⽤ getter 函数来计算
- 它适⽤于计算⽐较消耗性能的计算场景
- 必须要有一个返回值
watch
-
它更多的是起到 “观察” 的作⽤,类似于对数据进行变化的监听并执行回调。 主要⽤于观察
props或 本组件data的值,当这些值发生变化时,执⾏处理操作 -
不一定要返回某个值
建议
- 当目的是进⾏数值计算,且依赖于其他数据,那么推荐使用
computed - 当需要在某个数据发生变化的, 同时做⼀些稍复杂的逻辑操作,那么推荐使⽤
watch
5. Vue双向绑定原理?
在 Vue 2.x 中,利⽤的是 Object.defineProperty 去劫持对象的访问器(Getter、Setter),
当对象属性值发⽣变化时可获取变化,然后根据变化来作后续响应;(一个一个的劫持)
在 Vue 3.0 中,则是通过 Proxy 代理对象进⾏类似的操作。劫持的是整个对象, 只要对象中的属性变化了, 都能劫持到
5.1 Object.defineProperty和Proxy的优缺点?
Proxy
-
可以直接监听整个对象,⽽⾮是对象的某个属性
-
可以直接监听数组的变化
-
拦截⽅法丰富:多达13种,不限于
getsetdeleteProperty、has等。比
Object.defineProperty强大很多
Object.defineProperty
- 兼容性较好(可⽀持到 IE9)
- 可通过can i use 网站进行查看各浏览器是否兼容支持
6. 如何理解Vue的响应式系统?
Vue的响应式系统基本还是建立与在 M: model数据模型, V:view视图模型, VM: viewModel视图数据模型上
双向绑定的响应式原理还是基于Vue的 MVVM模式设计
- 视图变化了, 数据自动更新 => 监听原生的事件即可, 输入框变了, 监听输入框input事件
- 数据变化了, 视图要自动更新 => 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 监听到数据变化, 就根据依赖关系, 派发更新。
用图的方式来看“观察者模式”会清晰很多
7. 如何处理 打包出来的项目(首屏)加载过慢的问题
SPA应用: 单页应用程序, 所有的功能, 都在一个页面中, 如果第一次将所有的路由资源, 组件都加载了, 就会很慢!
加载过慢 => 一次性加载了过多的资源, 一次性加载了过大的资源
- 加载过多 => 路由懒加载, 访问到路由, 再加载该路由相关的组件内容
- 加载过大 => 图片压缩, 文件压缩合并处理, 开启gzip压缩等
比如:
-
配置异步组件, 路由懒加载
const login = () => import('../pages/login.vue') -
图片压缩: 使用 webp 格式的图片, 提升首页加载的速度
-
CDN加速: 配置CDN加速, 加快资源的加载效率 (花钱)
-
开启 gzip 压缩 (一般默认服务器开启的, 如果没开, 确实可能会很慢, 可以让后台开一下)