原理
组件化和MVVM
- 组件的出现,就是为了拆分代码,以不同的组件划分不同的功能模块,有复用性
- 传统组件,只是静态渲染,更新还要依赖于操作DOM
- MVVM的数据驱动视图则可以专注于业务逻辑和数据的开发,利用双向数据绑定去更新视图。
- Model-View-ViewModel 的缩写,Model代表数据模型,View代表 UI 组件,ViewModel 将Model 和View 关联起来。
- 数据会绑定到ViewModel 层并自动将数据渲染到页面中,视图变化的时候会通知ViewModel层更新数据。
Vue响应式
响应式的原理:
侦测数据的变化,收集视图依赖了哪些数据,数据变化时,自动“通知”需要更新的视图部分,并进行更新。三个步骤对应的专业术语就是:数据劫持 / 数据代理,依赖收集,发布订阅模式。
数据劫持的核心API:Object.defineProperty:
- 如何监听对象,监听数组
- 复杂对象,如何深度监听
- Object.defineProperty的缺点,为什么会被取代:
- 深度监听的时候,需要递归到底,一次性计算量大
- 无法监听新增/删除属性(需要Vue.set/Vue.delete去完成)
- 无法原生监听数组,需要特殊处理
- vue3改用的Proxy
- Proxy 的代理是针对整个对象的,而不是对象的某个属性,因此不用遍历对象每个属性
- Proxy 只需要做一层代理就可以监听同级结构下的所有属性变化
- 当然对于深层结构,递归还是需要进行的。此外Proxy支持代理数组的变化
- Proxy兼容性不好,且无法polyfill
Object.defineProperty实现数据劫持代理:
let data = {
name: 'lee',
age: 30,
info: {
address: '深圳'
},
arr: [1, 2, 3, 4, 5]
}
//重新定义数组原型
// Object.create()会创建新对象,原型指向Array.prototype,再扩展新的方法不会影响原型
const arrProto = Object.create(Array.prototype)
let methods = ['pop', 'shift', 'unshift', 'sort', 'reverse', 'splice', 'push']
methods.forEach(item =>