
定于数据角度对比:
ref 用来定义:基本类型数据
reactive 用来定义对象、数组类型的数据,注意reactive不能定义基本类型
备注:ref也可以用来定义对象或数组类型数据,它内部会自动通过 reactive
转为代理对象
原理角度对比:
ref 通过 Object.defineProperty()
的 get 与 set 来实现响应式的(数据劫持)
reactive 通过使用 Proxy
来实现响应式(数据劫持),并通过Reflect 操作源对象内部的数据。
使用角度对比:
ref 定义的数据:操作数据需要 .value
,读取数据时模版中直接读取不需要 .value
reactive 定义的数据:操作数据与读取数据,均不需要 .value
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h2>Vue3.0 响应式原理 —— Proxy()</h2>
<script>
// 源数据
let obj = {
name: '小明',
age: 18
}
// vue3 => Proxy() => 惰性更新
const p = new Proxy(obj, {
// 读取
get(target, propName) {
// 函数的默认返回值 undefined
console.log(`读取到了P的${propName}属性`)
// return target[propName]
return Reflect.get(target, propName)
},
// 修改、增加
set(target, propName, value) {
console.log(`修改了P的${propName}属性,值为${value}`)
// target[propName] = value
return Reflect.set(target, propName, value)
},
// 删除
deleteProperty(target, propName){
console.log(`删除到了P的${propName}属性`)
// return delete target[propName]
return Reflect.deleteProperty(target, propName)
}
})
// Vue2 => $set() 不怎么聪明
// Object.defineProperty(obj, {
// get: function(){
// },
// set: function() {
// }
// })
</script>
</body>
</html>
使用效果如下图
