Fork me on GitHub

Vue的响应式原理

什么是响应式

  • 修改 data 属性之后, vue 立刻监听
  • data 属性被代理到 vm 上

Object.defineProperty

  • 用法:

    // obj:必需,目标对象。
    // prop:必需,需定义或修改的属性的名字。
    // descriptor:必需,目标属性所拥有的特性。
    Object.defineProperty(obj, prop, descriptor)
  • 一个简单例子:

    var obj = {}

    var name = 'zhangsan'

    Object.defineProperty(obj, "name", {
    get: function () {
    console.log('get')
    return name
    },
    set: function (newVal) {
    console.log('set')
    name = newVal
    }
    })

    console.log(obj.name) // 可以监听到
    obj.name = 'lisi' // 可以监听到
  • 模拟Vue响应式:

    var vm = {}

    var data = {
    name: 'zhangsan',
    age: 18
    }

    for (var key in data) {
    // 闭包,新建一个函数,保证key的独立的作用域
    (function (key) {
    Object.defineProperty(vm, key, {
    // 监听get可以提高性能,data中有许多属性,有的被用到,有的不被用到,被用到的会走get,不被用到的不走get,未走get的属性,set的时候我们也无需关心,避免不必要的重复渲染
    get: function () {
    console.log('get', data[key])
    return data[key]
    },
    set: function (newVal) {
    console.log('set', newVal)
    data[key] = newVal
    }
    })
    })(key)
    }