- Vue响应式原理.
- Vue响应式实现.
响应式原理
初学者可能都会有这么一个疑惑. “为什么在data数据发生变化的时候,页面会被重新渲染”. 这个问题的答案是Vue内部会遍历data里面所有的属性,并使用Object.defineProperty
将这些属性全部转换为getter/setter
。将来Vue内部可以通过Object.defineProperty
追踪依赖,当有data里面的属性发生改变时会触发setter,我们可以在里面做响应式操作(例如:数据发生改变通知组件进行更新).
响应式实现
class MyVue {
// 接收将来传进来的参数
constructor (options) {
this.$options = options;
this.$data = options.data;
// 数据响应式
this.observe (this.$data);
// created生命周期
if(options.created)
{
options.created.call(this);
}
}
observe (obj) {
// 1. 判断传进来的东西是否是我们想要的内容.
if (!obj && typeof obj === 'object') {
return;
}
//2. 遍历该对象. 因为data里面可以存放很多个属性.
Object.keys (obj).forEach (key => {
// 做响应式
this.defineReactive (obj, key, obj[key]);
});
}
defineReactive (obj, key, value) {
Object.defineProperty (obj, key, {
get () {
// 将来读取 obj.key时将会触发 getter
return value;
},
set (newVal) {
//判断新值与旧值是否一样,一样则不需要进行更新.
if (value === newVal) {
return;
}
value = newVal;
console.log (`${key}属性更新了,更新的值为${value}`);
},
});
}
}
使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<script src="MyVue1.js"></script>
</head>
<body>
<div id="app"></div>
<script>
let vm = new MyVue({
el: '#app',
data: {
name: 'HelloVue!',
},
created() {
// 3ms之后修改name的值
// 会触发 setter
setTimeout(() => {
this.$data.name = '你好,Vue';
}, 3000);
},
});
</script>
</body>
</html>
效果演示:
打开html,在控制台窗口等待3秒将会提示
name属性更新了,更新的值为: 你好,Vue