Vue响应式原理代码
const data = { name: 'mushan', age: 18, shan: { name: '木杉', age: 18, obj: {} }, arr: [1, 2, 3] } const arrayProto = Array.prototype; const arrayMethods = Object.create(arrayProto); ['push', 'pop', 'shift', 'unshift' ,'sort', 'splice', 'reverse'].forEach(method => { arrayMethods[method] = function () { arrayProto[method].call(this, ...arguments); render(); } }) function defineReactive (data, key, value) { observer(value); Object.defineProperty(data, key, { get () { return value; }, set (newVal) { if(value === newVal) { return; } value = newVal; render(); } }) } function observer (data) { if(Array.isArray(data)) { data.__proto__ = arrayMethods; return; } if(typeof data === 'object') { for(let key in data) { defineReactive(data, key, data[key]) } } } function render () { console.log('页面渲染啦'); } function $set (data, key, value) { if(Array.isArray(data)) { data.splice(key, 1, value); return value; } defineReactive(data, key, value); render(); return value; } function $delete(data, key) { if(Array.isArray(data)) { data.splice(key, 1); return; } delete data[key]; render(); } observer(data);
利用vue2中Object.defineProperty实现响应式的劣势
- 天生就需要进行递归
- 监听不到数组不存在的索引的改变
- 监听不到数组长度的改变
- 监听不到对象的增删