使用Object的defineProperty实现数据劫持功能(vue2数据劫持),一个简单的版本,再次做个记录总结一下。
const data = {
name: 'zhm',
age: 10,
friend: {
friendName: '测试'
},
colors: ['blue']
}
// 变成响应式数据
let oldArrayProto = Array.prototype
// 给新对象的__proto__设置为oldArrayProto
let newArrayProto = Object.create(oldArrayProto)
let methods = ['push', 'shift', 'unshift', 'pop', 'splice']
methods.forEach(methodName => {
newArrayProto[methodName] = function () {
console.log('视图更新')
oldArrayProto[methodName].call(this, ...arguments)
}
})
// console.log(oldArrayProto)
// console.log(newArrayProto)
// 把数据变成响应式
observer(data)
function observer (target) {
if (typeof target !== 'object' || typeof target === 'null') {
return target
}
for (let key in target) {
defineReactive(target, key, target[key])
}
}
function defineReactive (target, key, value) {
// 深度监听
// console.log(key)
observer(value)
if (Array.isArray(target)) {
target.__proto__ = newArrayProto
}
Object.defineProperty(target, key, {
get () {
// observer(value)
return value
},
set (newValue) {
observer(newValue)
if (newValue !== value) {
value = newValue
console.log('视图更新')
}
}
})
}
// data.friend.friendName = '不测试'
// data.age = { num: 10 }
// data.age.num = 20
// data.colors.push('blue')