vue3为什么提供了ref和reactive两个将数据变为响应式的方法

一、回答

reactive:使用Proxy对复合类型数据进行劫持,使用reactive方法包装后即可得到响应式的数据。

ref:vue3将普通类型的数据用ref函数包装成带有value属性的实例对象,该实例对象由vue3定义的名为RefImpl类生成。

        既然要转换为带有value属性的对象,为什么不使用Proxy进行代理?原因是Proxy不止可以劫持数据获取和修改还能劫持其他功能。而普通数据类型仅需要监听获取和修改,所以出于性能的考虑并没有使用Proxy对其进行劫持,而是使用了Class中get和set关键字修饰自定义的value属性进行数据获取和变化的追踪。注意并不是vue2使用的Object.defineProperty。

        ref函数既可以传递普通类型又能传递对象类型,它内部进行了参数类型的判断,如果是对象类型,它将由reactive函数进行包装,但是获取和更改时仍要使用 .value进行操作。

二、简单实现reactive和ref的示例

1.简单实现的reactive示例(非源码)。可以劫持到对象people的取值及变化

// 使用Proxy代理
function reactive(obj) {
    let proxyPeople = new Proxy(obj, {
        get: (target, key) => {
            console.log(`获取了${key}属性`)  // 获取了age属性
            return target[key]
        },
        set: (terget, key, newVal) => {
            console.log(`设置了${key}属性,新值为${newVal}`)  // 设置了age属性,新值为18
            terget[key] = newVal
        }
    })
    return proxyPeople
}

// 要代理的原始数据
let people = reactive({
    name: '小明'
})

// 添加属性
people.age = 18
console.log(people); // Proxy(Object) {name: '小明', age: 18}
console.log(people.age); // 18

2.简单实现的ref示例(非源码)。可以劫持到变量name的取值及变化

// 使用class关键字
function ref(variable) {
    class RefImpl {
        constructor(_value) {
            this._value = _value
        }
        get value() {
            console.log(`取值为${this._value}`)  // 取值为小明  // 取值为小红
            return this._value
        }
        set value(newVal) {
            console.log(`新值为${newVal}`)  // 新值为小红
            this._value = newVal
        }
    }
    return new RefImpl(variable)
}

let name = ref('小明')
console.log(name); // RefImpl {_value: '小明'}
console.log(name.value); // 小明

name.value = '小红'
console.log(name.value); // 小红

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值