Object.defineProperty 应用
const data = {};
let name = 'hello';
Object.defineProperty(data, 'name', {
get: function() {
console.log('>>> get');
return name;
},
set: function(newVal) {
name = newVal;
console.log('>>> 更新视图');
}
})
data.name;
data.name = 'world';
基本实现
const data = {
name: 'zhangsan',
age: 28
}
observer(data)
function observer(target) {
if (typeof target !== 'object' || target === null) {
return target;
}
for (let key in target) {
defineReactive(target, key, target[key]);
}
}
function defineReactive(target, key, value) {
Object.defineProperty(target, key, {
get() {
return value;
},
set(newVal) {
if(newVal !== value) {
value = newVal;
console.log('>>> 更新视图')
}
}
})
}
data.name = 'lisi'
实现深度监听
const data = {
name: 'zhangsan',
age: 28,
friend: {
name: 'wangwu'
}
}
observer(data)
function observer(target) {
if (typeof target !== 'object' || target === null) {
return target;
}
for (let key in target) {
defineReactive(target, key, target[key]);
}
}
function defineReactive(target, key, value) {
observer(value)
Object.defineProperty(target, key, {
get() {
return value;
},
set(newVal) {
if(newVal !== value) {
value = newVal;
console.log('>>> 更新视图')
}
}
})
}
data.friend.name = 'wangwu2'
监听增加的数据层级
const data = {
name: 'zhangsan',
age: 28,
}
observer(data)
function observer(target) {
if (typeof target !== 'object' || target === null) {
return target;
}
for (let key in target) {
defineReactive(target, key, target[key]);
}
}
function defineReactive(target, key, value) {
observer(value)
Object.defineProperty(target, key, {
get() {
return value;
},
set(newVal) {
observer(newVal)
if(newVal !== value) {
value = newVal;
console.log('>>> 更新视图')
}
}
})
}
data.age = { number: 25}
data.age.number = 27
数组方法响应式实现
const oldArrayProto = Array.prototype;
const newArrayProto = Object.create(oldArrayProto);
['push', 'pop', 'shift', 'unshift', 'splice'].forEach((method) => {
oldArrayProto[method].call(this, ...arguments);
console.log('更新视图');
})
function observer(target) {
if (typeof target !== 'object' || target === null) {
return target;
}
if (Array.isArray(target)) {
target.__proto__ = newArrayProto;
}
for (let key in target) {
defineReactive(target, key, target[key]);
}
}
function defineReactive(target, key, value) {
...
}
vue2 实现响应式的不足
- 数据层级很深的时候,一开始就需要设置全部数据的监听,很费性能;
- data 新增或者删除属性不能监听到;
- 数组方法不能原生实现监听,需要额外处理;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
2021-03-29 Vue2 的响应式