Vue的响应式原理

本文介绍了响应式的概念,即当数据变化时,依赖于该数据的表达式能够自动更新。在Vue2.0中,通过Object.defineProperty()实现响应式,而在Vue3.0中,利用Proxy和ref提供了更强大的响应式能力,包括对对象整体的监听和删除操作的支持。同时,文章对比了两者的优缺点,并展示了具体的代码示例。
摘要由CSDN通过智能技术生成

1.什么是响应式?

同步状态下,JavaScript代码是自上而下执行的

let count = 1
let getDouble = n => n * 2
let double = getDouble(count)
consolle.log(count, double) // 1   2

count = 2
double = getDouble(count)
console.log(count, double) // 2 4

double的值是count乘以2得到的结果;如果我们能让getDouble函数随着count的变化而自动执行。那么这就是响应式。

2.Vue的响应式解决方案

(1)Vue2.0使用Object.defineProperty() MDN文档

读取到count属性时会触发get,修改count时会触发set。在触发set时截取,并修改double的值。

let obj = {}
let count = 1
let getDouble = n => n * 2
let double = getDouble(count)
console.log(double) //2

Object.defineProperty(obj, 'count', {
	get() {
		return count
	},
	set(val) {
		count = value
		double = getDouble(value)
	}
})
let obj.count = 2
console.log(double) //4

但是在Object.defineProperty()中删除obj.count的时候,set是不执行的,所以double是无法改变的。为了让删除某个数据可以响应式,Vue实现了$set、$delete以及数组变异方法等API。

(2)Vue3.0使用Proxy(reactive)、value setter(ref)来解决。ProxyMDN文档

Proxy更进步的地方是它可以监听整个对象,并且可以删除。其次它还可以监听不存在的属性,以及更丰富的数据结构比如Map、Set。
缺点:兼容不了IE11(被淘汰的laji不用管,还是chorme屌)
如上:读取到count属性时会触发get,修改count时会触发set,delete时会触发deleteProperty。在触发set和delete时截取,并修改double的值。

let obj = {
    count: 1
}
let getDouble = n => n * 2
let double = getDouble(obj.count)
let proxy = new Proxy(obj, {
    get: (target, prop) => {
        return target[prop]
    },
    set: (target, prop, value) => {
        target[prop] = value
        if(prop === 'count') {
            double = getDouble(value)
        }
    },
    deleteProperty(target, prop) {
        delete target[prop]
        if(prop === 'count') {
            double = NaN
        }
    }
})
console.log(obj.count, double) // 1  2
proxy.count = 2
console.log(obj.count, double) // 2  4
delete proxy.count
console.log(obj.count, double) // undefined  NaN

Vue3.0的ref()使用对象的get、set函数进行监听。这种响应式的方式只能拦截一个属性。

let getDouble = n => n * 2
let _value = 1
let double = getDouble(_value)
let count = {
	get value() {
		return _value
	},
	set vlaue(val) {
		_value = val
		double = getDouble(_value)
	}
}
console.log(count.value, double) // 1  2
count.value = 2
console.log(count.vauel, double) // 2  4
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jasper-web

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值