写在前面
Vue
响应式原理是数据驱动视图的核心,它能够自动帮助开发者监听数据的变化,最终触发视图更新。它是Vue
的渲染更新过程的核心。那么了解这一部分的原理至关重要,这篇文章就结合vue2
和vue3
响应式来做一个对比,既明白了响应式原理的实现,又对比了二者在性能上的差异~
需要了解的api
这篇文章不是零基础,需要对一些基础api
有一定的了解,那么这里给出这些api
的官方文档,供大家参考学习:
- vue2响应式原理
Object.defineProperty
- vue3响应式原理
Proxy
Reflect
准备一个原始对象数据
为了做这个实验,我使用同一个数据对象来分别做vue2
和vue3
的示例:注意这个data数据从最外层花括弧到最里层总共8个层级,你可以数一下。
const data = {
username: 'tom',
profile: {
city: 'beijing',
a: {
b: 12,
c: {
d: 23
}
}
}
}
接下来我分别写点代码对这个数据做响应式处理:
- vue2
const data = {
username: 'tom',
profile: {
city: 'beijing',
a: {
b: 12,
c: {
d: 23
}
}
}
}
function observe(data) {
console.log(1);
if (typeof data !== 'object' || data == null) {
return data
}
for (const key in data) {
defineReactive(data, key, data[key])
}
}
function defineReactive(target, key, val) {
observe(val)
Object.defineProperty(target, key, {
get() {
console.log(`get ${key}`);
return val
},
set(newValue) {
console.log(`set ${key}`);
if (newValue !== val) {
observe(newValue)
val = newValue
}
}
})
}
observe(data);
console.log(data);
打印的结果如下:
从图中可以清晰的看到总共打印了8次1,也就是说observe
一共执行了8次;由此可见vue2是一次递归到底的来实现响应式的,好接下来看看vue3:
- vue3
function observe(data) {
console.log(1);
if (typeof data !== 'object' || data == null) {
return data
}
const p = new Proxy(data, {
get(target, key, receiver) {
console.log(`get ${key}`)
const result = Reflect.get(data, key, receiver)
// 当获取值的是时候 再设置响应式
return observe(result)
},
set(target, key, val, receiver) {
console.log(`set ${key}`)
const result = Reflect.set(target, key, val, receiver)
return result
}
})
return p
}
const data = {
username: 'tom',
profile: {
city: 'beijing',
a: {
b: 12,
c: {
d: 23
}
}
}
}
const p1 = observe(data)
console.log(p1)
打印结果如图:
只打印了一次1,也就是说observe
只执行了一次,从代码可以看出,将来执行get的时候,observe
又会再次执行。什么意思呢?也就是说Vue3
对于数据的深层监听只有当获取值的时候才会响应式处理,这样在性能上肯定会提升很多。
争议
读到这里,抛开其他细节来讲,可能你会来句卧槽,那Vue2
也可以在get
的时候observe
啊,确实如此,但是想一下是不是会有点问题呢?问题就在于每次执行get
的时候,不管是获取哪个属性,都需要执行一下observe
,并且它还是会向下遍历,这样增加了时间复杂度,可想而之,其性能是多么浪费的,还不如一次性深度监听到底呢?而proxy
则不一样,它只会响应式处理你get
的那个层级,它不会深度遍历,这样解释你明白了吗?
总结
接下来总结一下二者响应式的差异
- Object.defineProperty
- 深度监听,性能问题
- 新增删除属性问题,这个可以参考我前面写的一个文章总结一下Vue那些常用必会面试必考的API,这里说明了
vue2
为什么需要set&delete
两个api
- 数组问题,需要重写数组原型的几个方法
- Proxy
- 性能提升了一大截
- 解决了vue2的那些问题
- 兼容性有待处理
当然示例代码都没做优化,实际上源码肯定是对各种情况还做了处理,这里就不做介绍了,可以自己去看源码哈~如果你对本文有什么看法或者觉得不对的地方,请在评论区赐教!共勉进步~~
参考
vue2响应式原理
vue3响应式原理
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!