- vue响应式原理 vue2.0的响应式原理依靠的es5的Object.defineProperty来实现的 Object.defineProperty传入3个参数,第一个是要监听的,第二个是要监听的属性,第三个是一个对象包含两个函数set和get,分别在获取和改变这个对象的属性时调用。 我们在这里使用这个函数实现以下vue响应式原理(页面更新即触发log输出)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>vue2响应式原理</title>
</head>
<body>
</body>
<script>
const data = {
name: 杰哥,
age: 20,
friend: {
friendName: 灼子,
girlFriend: { girlFriendName: 娟子 },
},
color: [red, orange, green]
}
// 重写一个数组原型,来重写数组的一些基本方法如push等,来监听数组元素这些方法的调用
const oldArrayProto = Array.prototype;
const newArrayProto = Object.create(oldArrayProto);
[push, pop, unshift, shift].forEach(menthodName => {
newArrayProto[menthodName] = function () {
console.log(更新视图 + menthodName);
oldArrayProto[menthodName].call(this, ...arguments);
}
})
// 绑定监听事件
observer(data);
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) {
//这里是处理深层对象的数据,进行深层监听
observer(value);
Object.defineProperty(target, key, {
get: function () {
return value;
},
set: function (newValue) {
// 数据改变的时候也要更新监听
observer(newValue);
if (newValue !== value) {
console.log(更新视图: + value + => + newValue);
value = newValue;
}
}
})
}
// 正常测试
data.name = 杰哥2.0;
data.friend.friendName = 灼子2.0;
data.friend.girlFriend.girlFriendName = 娟子2.0;
// 数组测试
// data.color[0] = blue;
data.color.push(blue);
// 弱点测试
delete data.age;
//的时候不会触发监听事件,这是vue2.0的弱点,在vue2中使用 Vue.delete
data.test = something;
// 这种情况也不会触发监听事件,在vue中使用Vue.set
</script>
</html>