Vue 3 深刻响应性原理

深刻响应性原理

终于到了讲解咱们 Vue 的响应式原理,前面咱们已经讲解了 MapWeakMapSetWeakSetProxyReflect 这几个知识点。那么接下来思考下到底什么是响应式,就好比咱们作一个公司的官网,而后要求必须兼容手机端,ipad 端,电脑端,内容屏幕大小变化而变化,这些就须要依赖 JavaScript,CSS, HTML 去处理了。ide

那么假如咱们像在 Excel 表格中,两个数字相加,若是一个数字变化了,两个数字的和确定得变化吧,Excel 表格作到了,可定里面是作了很大的处理了,那若是使用 JavaScript 来作,咱们该如何作呢?函数

let var1 = 2
let var2 = 3

let sum = var1 + var2

// 当 var1 变化时,

// 该如何通知 sum

若是咱们更新第一个值,sum 不会被修改。this

那么咱们如何用 JavaScript 实现这一点呢?url

  • 检测其中某一个值是否发生变化
  • 用跟踪 (track) 函数修改值
  • 用触发 (trigger) 函数更新为最新的值

Vue 如何追踪变化?

在 Vue 中,在将一个对象数据传递给一个组件的时候,Vue 已经给我这些数据设置了 settergetter 属性,一旦数据发生变化,就会获得响应,这其中就是 ProxyReflect 的很大的功劳。spa

经过前面的知识,咱们知道 Proxy 是一个包含另外一个对象或函数并容许你对其进行拦截的对象。3d

let obj = {
    var12,
    var23,
    sum0,
}
let handlerObj = {
    get(target, prop) {
        if(prop == 'sum') {
            target['sum'] = target['var1'] + target['var2']
            return target['sum']
        }
        return target[prop]
    },
    set(target, prop, newVal) {
        target[prop] = newVal
    }
}
let p = new Proxy(obj, handlerObj)
console.log(p.sum)

图片

此外,Proxy 还提供了另外一个特性。咱们没必要像这样返回值:target[prop],而是能够进一步使用一个名为 Reflect 的方法,它容许咱们正确地执行 this 绑定,就像这样:
code

let obj = {
    var12,
    var23,
    sum0,
}
let handlerObj = {
    get(target, prop) {
        if(prop == 'sum') {
            target['sum'] = target['var1'] + target['var2']
        }
        return Reflect.get(...arguments)
    },
    set(target, prop, newVal) {
        target[prop] = newVal
    }
}
let p = new Proxy(obj, handlerObj)
console.log(p.sum)

图片

上面咱们已经检测到了哪些数据发生了变化,因此接下来咱们须要用一个咱们还没实现的 track 追踪方法来进行修改:
orm

let obj = {
    var12,
    var23,
    sum0,
}
let track = (target, prop) => {
    if(prop == 'sum') {
        target['sum'] = target['var1'] + target['var2']
    }
}
let handlerObj = {
    get(target, prop) {
        track(target, prop)
        return target[prop]
    },
    set(target, prop, newVal) {
        target[prop] = newVal
    }
}
let p = new Proxy(obj, handlerObj)
console.log(p.sum)

图片

最后,当某些内容发生改变时咱们会设置新的值。为此,咱们将经过触发这些更改来设置新 Proxy 的更改:
对象

let obj = {
    var12,
    var23,
    sum0,
}
let track = (target, prop) => {
    if(prop == 'sum') {
        target['sum'] = target['var1'] + target['var2']
    }
}
let trigger = (target, prop, newVal) => {
    target[prop] = newVal
}
let handlerObj = {
    get(target, prop) {
        track(target, prop)
        return target[prop]
    },
    set(target, prop, newVal) {
  trigger(target, prop, newVal)
        
        return Reflect.set(...arguments)
    }
}
let p = new Proxy(obj, handlerObj)
console.log(p.sum)

图片

  • 当某个值发生变化时进行检测:咱们再也不须要这样作,由于 Proxy 容许咱们拦截它
  • 跟踪更改它的函数:咱们在 Proxy 中的 getter 中执行此操做,称为 effect
  • 触发函数以便它能够更新最终值:咱们在 Proxy 中的 setter 中进行该操做,名为 trigger
相关文章
相关标签/搜索