对Vue数据响应式的总结

62 阅读1分钟

数据响应式是vue的核心原理。

实现原理

借助Object.defineProperty(),利用proxy的设计模式实现。 我们通过Object.defineProperty为对象obj添加属性,可以设置对象属性的gettersetter方法。之后我们每次通过点语法获取属性都会执行这里的getter函数,在这个函数中我们会把调用此属性的依赖收集到一个集合中 ;而在我们给属性赋值(修改属性)时,会触发这里定义的setter函数,在次函数中会去通知集合中的依赖更新,做到数据变更驱动视图变更。

实现原理的demo:

    let myData = {n=0}
    let data = proxy({data:myData})
    
    function proxy({data}) { //解构赋值
        let value = data.n
        
        Object.defineProperty(data, 'n', {
            get() {
                return value
            }
            set(newValue) {
                value = newValue
            }
        })
        
        const obj = {}
        Object.defineProperty(obj, 'n', {
            get() {
                return data.n
            },
            set() {
                data.n = value
            }
        })
    }

这个原理导致它又一些bug:当出现未被定义的key时,无法进行响应式。

一般解决办法

  1. 先声明,再使用
  2. 使用Vue.setthis.$set来修改(使用后,该key就有了响应式功能)

数组的mutation method

数组的操作如push等无法用以上两个方法解决,于是Vue篡改了数组的7个API,解决了响应问题。