返回 处理入口:
重新给
Vue.js 数据响应式原理,处理入口探秘
前端
2023-12-02 22:09:44
在 Vue.js 的世界里,数据响应式是其核心的基石之一,它允许我们在数据发生变化时,自动更新视图,从而实现数据的双向绑定。那么,Vue.js 是如何实现数据响应式的呢?本文将带您深入了解 Vue.js 数据响应式原理的处理入口,通过源码分析,探究 vm.msg = { count: 0 }
重新给属性赋值时,响应式系统如何进行处理,揭示数据响应式的实现机制,帮助您理解 Vue.js 的核心原理。
处理入口:set
函数
在 Vue.js 中,当我们给一个响应式数据属性重新赋值时,会触发 set
函数。这个函数是数据响应式系统处理入口,它负责将新值与旧值进行比较,如果发现新值与旧值不同,则触发更新视图的过程。
Object.defineProperty(data, key, {
enumerable: true,
configurable: true,
get: function reactiveGetter() {
const value = getter ? getter.call(obj) : obj[key]
if (Dep.target) {
dep.depend()
}
return value
},
set: function reactiveSetter(newVal) {
const value = getter ? getter.call(obj) : obj[key]
if (newVal === value || (newVal !== newVal && value !== value)) {
return
}
const oldValue = value
if (isRef(value) && !isRef(newVal)) {
value.value = newVal
} else {
obj[key] = newVal
}
dep.notify()
}
})
set
函数的工作原理
set
函数首先会比较新值与旧值是否相等。如果相等,则不会做任何处理。这是因为 Vue.js 采用了“值比较”策略,即只有当新旧值不严格相等时,才会触发更新视图的过程。
如果新值与旧值不相等,则 set
函数会执行以下操作:
- 如果新值是
Ref
对象,并且旧值不是Ref
对象,则将旧值的.value
属性设置为新值。这是因为Ref
对象是一个引用类型,当我们重新给Ref
对象赋值时,实际上是改变了其.value
属性的值,而不是整个Ref
对象本身。 - 如果新值不是
Ref
对象,或者旧值也是Ref
对象,则直接将旧值替换为新值。 - 调用
dep.notify()
方法,通知所有依赖于该属性的观察者(Watcher
实例),让它们更新视图。
重新给 vm.msg
赋值
现在,让我们回到 vm.msg = { count: 0 }
这个例子。当我们重新给 vm.msg
赋值时,会发生以下情况:
set
函数被触发。set
函数比较新值{ count: 0 }
与旧值undefined
,发现不相等。set
函数将旧值undefined
替换为新值{ count: 0 }
。set
函数调用dep.notify()
方法,通知所有依赖于vm.msg
属性的观察者(Watcher
实例),让它们更新视图。
由于 vm.msg
属性是一个对象,因此它包含多个子属性,如 count
。当我们重新给 vm.msg
赋值时,不仅 vm.msg
本身发生了变化,其子属性 count
也发生了变化。因此,所有依赖于 vm.msg
属性或其子属性的观察者(Watcher
实例)都会被通知更新视图。
总结
通过本文的分析,我们了解了 Vue.js 数据响应式原理的处理入口 set
函数,以及它在 vm.msg = { count: 0 }
重新给属性赋值时所扮演的角色。希望这些内容能帮助您更深入地理解 Vue.js 数据响应式的实现机制。