在vue3中的组合api中,对响应式api做了一些改动。在reactiveapi中,比较重要的两个是ref和reactive。但是对于这两种区别和使用场景,大部分同学都比较困惑。本文将为大家详细介绍这两者的区别以及使用场景的区别。在理解之前,我们需要知道js中有哪些原始类型,其中number、string、boolean、undefined、null是一些原始的基本类型。对于这些value、ref和reactive的用法有什么区别?ref对于ref,原始类型和对象都可以响应相应的数据进行处理,比如这种写法是可以的constref1=ref(0);//OKconstref2=ref({count:0})//OKref可以处理基本类型的值,也可以处理引用类型的值,官方文档中有说明。如果将一个对象传递给ref函数,那么这个对象会通过reactive()方法转化为一个深层次的反应对象,即内部本质还是调用了反应方法。reactivereactive方法不允许传递原始类型。值,它不会像ref一样检测原始类型并做相应的转换constreactive1=reactive(0);//NOTOKconstreactive2=reactive({count:0})//OKreactive1不会报错是的,你也可以在页面上渲染这个值,但是你没有办法改变它,所以它就失去了意义。对于反应式,它只能是一个对象。主要原因在于Vue内部响应式的实现,它是基于Proxy实现的,但是proxy不适用于基本类型的数据,所以ref既可以用于基本类型也可以用于引用类型,而reactive只适用于参考类型。需要以.value的形式进行,数据的更新也是以.value的形式进行constref1=ref(0);console.log(ref1.value);//0constref2=ref({count:0})控制台日志(ref2.value.count);//0ref1.value=1console.log(ref1.value);//1vue的模板语法中不需要带.value{{ref1}}
reactive因为是proxy代理的对象数据,可以直接获取不需要加上.valueconstreactive1=reactive({num:0});console.log(reactive1.num);//0更新和访问数据可以直接访问TS类型refref有一个特殊的属性.value,所以对于Its类型,可以直接从vue中导入,具体写法是这样的:import{ref,Ref}from'vue'constref1:Ref=ref(0);如果熟悉ts的话,这个并不陌生,reactive我就不细说了相对来说reactive的类型比较简单import{reactive}from'vue'constreactive1:{num:number}=reactive({数:0});传递给响应式函数的对象类型是什么,它将返回值对应的类型是什么?需要注意的一点是,如果对象中包含ref,此时ref不需要添加对应的类型,vue会自动解包import{reactive}from'vue'constreactive1:{num:number}=reactive({num:ref(0)});这种写法是没有问题的。使用watch监控ref和reactive的区别是不同的。可以直接监听ref的数据,这样,当ref的数据发生变化时,会执行watch函数对应的回调constref1=ref(0)watch(ref1,()=>{console.log('changed!')})当然这只是原始类型的数据。如前所述,ref可以传递对象。如果它是一个物体,它还能被监控吗?constref1=ref({num:1})watch(ref1,()=>{console.log('changed!')})//ref1.value.num=1当我执行ref1.value.num=1,它会打印改变吗!?答案是否定的,因为watch并没有对ref1进行深度监控,但是需要注意的是此时可以更新dom。如前所述,ref会将其转换为反应形式。如果想深入监控,只需要添加一个对应的参数即可constref1=ref({num:1})watch(ref1,()=>{console.log('changed!')},{deep:true})有了上面的基础,那么reactive就简单了。因为reactive本质上是一个对象,看的时候加深属性是本能的,但是vue对它进行了优化。使用watch监听reactive时,可以不加deep属性,也可以加deep属性。做深度监控constreactive1=reactive({num:1})watch(reactive1,()=>{console.log('changed!')})//reactive1.num=1上面的写法可以达到我们的目的想要效果总结那么什么时候用ref,什么场景下用reactive呢?虽然没有严格的规定,但在某些情况下最好使用一些特定的内容,当然你也可以refastud如果你需要响应式原始值,那么使用ref()是正确的选择,注意原始值。如果需要响应式对象,层次不深,也可以使用ref如果需要响应式可变对象,对象层次深,需要深度跟踪,那么可以使用reactive作为ref的子集,ref能解决一切烦恼。如果您有什么意见或意见,请留言并关注公众号【FE情报局】参考资料:https://dmitripavlutin.com/re...