vue源码学习--1.变化侦测篇(object)
// 源码位置:src/core/observer/index.js /** * Observer类会通过递归的方式把一个对象的所有属性都转化成可观测对象 */ export class Observer { constructor (value) { this.value = value // 给value新增一个__ob__属性,值为该value的Observer实例 // 相当于为value打上标记,表示它已经被转化成响应式了,避免重复操作 def(value,'__ob__',this) if (Array.isArray(value)) { // 当value为数组时的逻辑 // ... } else {
// 本文的对象 this.walk(value) } } walk (obj: Object) { const keys = Object.keys(obj); for (let i = 0; i < keys.length; i++) { defineReactive(obj, keys[i]) } } } /** * 使一个对象转化成可观测对象 * @param { Object } obj 对象 * @param { String } key 对象的key * @param { Any } val 对象的某个key的值 */ function defineReactive (obj,key,val) { // 如果只传了obj和key,那么val = obj[key] if (arguments.length === 2) { val = obj[key] }
// 如果要是对象里面还要对象,需要观测里面的对象变化情况,递归 if(typeof val === 'object'){ new Observer(val) } Object.defineProperty(obj, key, { enumerable: true, configurable: true, get(){ console.log(`${key}属性被读取了`); return val; }, set(newVal){ if(val === newVal){ return } console.log(`${key}属性被修改了`); val = newVal; } }) }
使用:
let car = new Observer({ 'brand':'BMW', 'price':3000 })