返回
彻底洞悉Vue数据响应式原理,不再是源码小白!
前端
2023-10-30 19:39:17
<p style=text-align:center;></p>
<p style=text-align:center;></p>
<p style=text-align:center;></p>
>**Vue源码学习(一):你不知道的数据响应式原理**
**前言**
当今的前端面试,越来越注重源码这一块了。而且就算没有面试,我想,每一个vue的使用者,在使用了一段时间的vue框架之后,也应该自觉去思考,这个框架是怎么实现的,他怎么就能这么方便呢?当然,这也不需要立马开始就读源码。Vue框架对于我们的初级工程师来说有点重量级。但是,如果你要进阶,你避不开源码。
所以,为了帮助大家更好的理解Vue框架,我决定开一个系列的文章,来详细介绍Vue的源码。本文是该系列的第一篇,主要内容是Vue的数据响应式原理。
**一、数据响应式原理概述**
数据响应式原理,是Vue框架的核心之一。它使得Vue能够自动侦听数据的变化,并在数据变化时自动更新视图。
**二、Vue如何实现数据响应式**
Vue实现数据响应式有两种方式:
* **利用ES6的Proxy特性**
* **通过Object.defineProperty()方法**
Vue主要使用的是第二种方式。
**三、Object.defineProperty()方法实现数据响应式原理**
```javascript
Object.defineProperty(data, key, {
enumerable: true,
configurable: true,
get: function() {
console.log('你访问了' + key + '属性!');
return value;
},
set: function(newValue) {
console.log('你设置了' + key + '属性的值!');
value = newValue;
updateView(); // 更新视图
}
});
四、Vue源码实现数据响应式原理
在Vue源码中,数据响应式原理是通过defineReactive()
函数实现的。
export function defineReactive (
obj: object,
key: string,
val: any,
customSetter?: Function
): void {
const dep = new Dep()
// 创建Dep实例,用来收集依赖
const property = Object.getOwnPropertyDescriptor(obj, key)
// 取出属性符
if (property && property.configurable === false) {
return
}
// cater for pre-defined getter/setters
const getter = property && property.get
const setter = property && property.set
if ((!getter || setter) && arguments.length === 2) {
val = obj[key]
}
// 收集依赖
let childOb = !isPrimitive(val) && observe(val)
// 递归实现响应式
Object.defineProperty(obj, key, {
enumerable: true,
configurable: true,
get: function reactiveGetter () {
// 依赖收集
const value = getter ? getter.call(obj) : val
if (Dep.target) {
dep.depend()
if (childOb) {
childOb.dep.depend()
// 如果是嵌套对象,递归进行依赖收集
}
}
return value
},
set: function reactiveSetter (newVal) {
const value = getter ? getter.call(obj) : val
/* eslint-disable no-self-compare */
if (newVal === value || (newVal !== newVal && value !== value)) {
return
}
// set操作,判断新值和旧值是否相等,不相等则触发更新
if (customSetter) {
customSetter()
}
// 调用getter触发依赖收集
const oldVal = val
val = newVal
dep.notify()
// 触发依赖更新
if (childOb) {
childOb.dep.notify()
// 如果是嵌套对象,递归触发依赖更新
}
}
})
}
五、总结
本文详细介绍了Vue数据响应式原理,从基本概念到核心实现,深入浅出,循序渐进,希望能够帮助您彻底理解Vue数据响应式原理。
如果您对Vue源码感兴趣,欢迎继续阅读我的系列文章。下一篇,我们将介绍Vue的虚拟DOM。