- 从定义数据角度对比:
- ref用来定义:基本类型数据。
- reactive用来定义:对象(或数组)类型数据。
- 备注:ref也可以用来定义对象(或数组)类型数据, 它内部会自动通过
reactive
转为代理对象。
- 从原理角度对比:
- ref通过
Object.defineProperty()
的get
与set
来实现响应式(数据劫持)。 - reactive通过使用Proxy来实现响应式(数据劫持), 并通过Reflect操作源对象内部的数据。
- 从使用角度对比:
- ref定义的数据:操作数据需要
.value
,读取数据时模板中直接读取不需要.value
。 - reactive定义的数据:操作数据与读取数据:均不需要
.value
。
// ref 方式
let name = ref('张三')
let age = ref(18)
let job = ref({
type:'前端工程师',
salary:'30K'
})
function changeInfo(){
// 实现响应式需要.value,
// console.log(name) 打印出来的是 RefImpl (reference implement 引用的实现) 的实例对象
name.value = '李四'
age.value = 48
// 遇到需要需改对象属性实现响应式时,也需要.value,但属性就不需要.value
// console.log(job.value) 打印出来的是 Proxy (window 自带 es6 的东西) 的实例对象
job.value.type.value = 'UI设计师' // 这种写法是错误的
job.value.type = 'UI设计师'
job.value.salary = '60K'
}
// reactive 方式
let person = reactive({
name:'张三',
age:18,
job:{
type:'前端工程师',
salary:'30K',
a:{
b:{
c:666
}
}
},
hobby:['抽烟','喝酒','烫头']
})
function changeInfo(){
// 不用像 ref 一样.value
// console.log(person) 打印出来的是 Proxy (window 自带 es6 的东西) 的实例对象
person.name = '李四'
person.age = 48
person.job.type = 'UI设计师'
person.job.salary = '60K'
person.job.a.b.c = 999
person.hobby[0] = '学习'
}