JavaScript

超轻量级php框架startmvc

vue源码学习之Object.defineProperty对象属性监听

更新时间:2020-07-11 11:06:01 作者:startmvc
本文介绍了vue源码学习之Object.defineProperty对象属性监听,分享给大家,具体如下:参考版本

本文介绍了vue源码学习之Object.defineProperty对象属性监听,分享给大家,具体如下:

参考版本 vue源码版本:0.11

相关

vue实现双向数据绑定的关键是 Object.defineProperty ,让我们先来看下这个函数。

在MDN上查看有关Object.defineProperty 的解释。

我们先从最简单的开始:


let a = {'b': 1};
Object.defineProperty(a, 'b', {
 enumerable: false,
 configurable: false,
 get: function(){
 console.log('b' + '被访问');
 },
 set: function(newVal){
 console.log('b' + '被修改,新' + 'b' + '=' + newVal);
 }
});

a.b = 2; // b被修改,新b=2
a.b; // b被访问

这样,我们就能监听对象了!但问题并不仅仅这么简单。。。

我们可能会有对象中属性的值还是对象这种嵌套情况,可以通过递归解决!

在vue源代码文件 srcobserveobserver.js 中


// 观察者构造函数
function Observer(data){
 this.data = data;
 this.walk(data);
}

let p = Observer.prototype;
p.walk = function(obj){
 let val;
 for(let key in obj){
 // 通过 hasOwnProperty 过滤掉一个对象本身拥有的属性 
 if(obj.hasOwnProperty(key)){
 val = obj[key];
 // 递归调用 循环所有对象出来
 if(typeof val === 'object'){
 new Observer(val);
 }
 this.convert(key, val);
 }
 }
};

p.convert = function(key, val){
 Object.defineProperty(this.data, key, {
 enumerable: false,
 configurable: false,
 get: function(){
 console.log(key + '被访问');
 },
 set: function(newVal){
 console.log(key + '被修改,新' + key + '=' + newVal);
 if(newVal === val) return ;
 val = newVal;
 }
 })
};

let data = {
 user: {
 name: 'zhangsan',
 age: 14
 },
 address: {
 city: 'beijing'
 }
}

let app = new Observer(data);
data.user.name; // user被访问 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

vue Object.defineProperty vue 对象属性监听 vue Object.defineProperty监听