Vue3 ref和reactive函数的使用和区别以及响应式

​ 在这里我会用通俗易懂的语言和浅层次的原理来帮助学习Vue的小伙伴去理解ref函数和reactive函数和二者的区别以及其响应式原理,帮助大家少走弯路。这里对于不会描述底层核心代码,想了解底层原理的小伙伴可以去看上篇。


ref函数:

语法:const xxx = ref (initValue)
接受的数据类型:基本类型,对象类型
作用:把参数加工成一个响应式对象,全称为reference对象(我们下面一律简称为ref对象)
核心原理:响应式依赖Object.defineProperty( )的get( )和set( )


Ref函数对于基本数据类型的参数
  • 基本使用
<template>
  <h2>{{Str}}</h2>
</template>

<script>
import {ref} from 'vue'
export default {
  setup(){
    const Str =ref('hello')
    return{
      Str
    }
  }
}
  这里我们定义了一个Str变量来接收ref加工生成的ref对象,我们都知道对象的数据都是以键值对的形式存储的,但是在这里为什么直接把Str给return出去,
并且模板里可以直接写Str这个对象呢,我们的源数据呢?带着这个疑问我们来输出一下Str

setup(){
    const Str =ref('hello')
    console.log(Str)
    return{
      Str
    }
  }

打印结果如下:
RefImpl
__v_isRef: true
_rawValue: "hello"
_shallow: false
_value: "hello"
value: "hello"
[[Prototype]]: Object

  在这里我们看到了ref对象身上的一个属性 value,没错,我们存入的值就对应在value属性上,至于为什么直接return出是Str而不是Str.value 。是因为Vue帮了我们
一个忙,我们在这里可以简写,return出去的Str 就相当于Str.value ,当然 非要写.value的形式也不是不可以。不过这里需要注意的是,在
setup函数中操作Str中的数据不可以简写。
  • 响应式原理
   对于基本数据类型说完了它的基本用法,下面我们来说说他的响应式原理,也就是我们为什么非要用一个ref对象来接受数据,而不是直接就定义好一个字符
串‘hello’然后去直接操作这个字符串?

  对于ref函数,数据参数和它加工生成的ref对象二者存在着某种“契约”,我们把加工好的参数也就是ref对象交出去之后,我们直接操作修改的就是ref
对象上的value属性,因为这个契约的存在,以至于在修改属性值的时候对应的源数据参数也会连同被修改,但在原数据被修改之前vue就会监听到我
们修改了数据,立马进行解析模板更新页面,这就是ref对象的响应式原理。这里的契约其实就是Object.defineProperty的get( )和set( )篇幅有
限我们不对底层核心代码做示范.

  我们知道了ref函数定义基本类型,下面会讲解reactive函数,该函数参数是对象类型和ref的对象类型参数有着千丝万缕的联系,所以学会reacti
ve函数学会了ref函数存储的对象数据类型也就自然理解了。

reactive函数:

语法:const xxx = ref (源对象)
接受的数据类型:对象类型
作用:把参数加工成一个代理对象,全称为proxy对象
核心原理:基于Es6的Proxy实现,通过代理操作源对象,相比于reactive定义的浅层次响应式数据对象,reactive定义的是更深层次的响应式数据对象


reactive对于对象类型的参数
  • 基本使用
    <template>
      <h2>姓名:{{Person.name}}</h2>
      <h2>薪水:{{Person.job.salary}}</h2>
    </template>
    
    <script>
    import {reactive} from 'vue'
    export default {
      setup(){
        const p ={
          name:'Ben',
          job:{
            salary:'30k'
          }
        }
        const Person =reactive(p)
        return{
          Person
        }
      }
    }
    
    这里不同于上面的ref函数,参数是一个对象类型的数据,那么对于接受返回值的Person对象也会和上面的ref对象一样都是把数据对应到value属性上吗?
    带着这个疑问打印一下Person对象
    
    Proxy
    [[Handler]]: Object
    [[Target]]: Object
    job: {salary: "30k"}
    name: "Ben"
    [[Prototype]]: Object
    [[IsRevoked]]: false
    
    我们发现Person对象身上并没有value属性并且Person对象是一个proxy类型的对象,这里我们可以理解为Person是一个加强版的p对象,对于p来说Person是一个代理对象,所以我们可以
    直接访问到自身的属性,而不是和ref函数一样把数据对应到value属性上,所以我们return出去的Person对象可以直接放在模板里读取属性
    
  • 响应式原理
       reactive的响应式是更加“深层次”的,底层依赖于ES6中的Proxy实现,用reactive函数加工出来的对象都是Proxy对象,无论原数据对象里面有多少层对象他们都会被加工成Proxy
    类型对象(深层次)。它的响应式核心思想和ref是大同小异的,这里我们定义的Person对象来代理p对象,二者也会建立“契约”,我们在把Person对象return出去
    后在我们操作修改Person对象的数据时,在原对象数据改变之前Vue都会监听到这一举动并且同时解析模板、更新页面。
    

Ref函数对于对象类型的参数

说到这里大家会有个疑问,ref定义对象类型的数据和这个reactive函数有什么关系呢?

ref对象只能去操作浅层次的数据,把基本数据类型当做自己的属性值,如果ref函数的参数是对象这种深层次的数据类型时它会求助一个人,这个人不是别人正是reactive函数,在底层Vue会把对象参数通过reactive函数加工成一个Proxy代理对象放到ref的value属性上

<template>
  <h2>姓名:{{Person.name}}</h2>
  <h2>薪水:{{Person.job.salary}}</h2>
</template>

<script>
import {reactive,ref} from 'vue'
export default {
  setup(){
    const p ={
      name:'Ben',
      job:{
        salary:'30k'
      }
    }
    const Person =ref(p)
    console.log(Person)
    return{
      Person
    }
  }
}

打印Person对象的结果:

RefImpl {_shallow: false, __v_isRef: true, _rawValue: {}, _value: Proxy}
__v_isRef: true
_rawValue: {name: "Ben", job: {}}
_shallow: false
_value: Proxy {name: "Ben", job: {}}
value: Proxy
[[Handler]]: Object
[[Target]]: Object
job: {salary: "30k"}
name: "Ben"
[[Prototype]]: Object
[[IsRevoked]]: false
[[Prototype]]: Object

我们可以很清楚的看到,value属性下对应的正是给p原数据对象加工生成Proxy对象


区别:

1.存储类型:ref对象可以接受基本数据类型得数据也可以接受对象类型的数据,而reactive只可以接受对象类型的数据

2.响应式:相比于ref对象reactive函数是更深层次的,ref函数参数为对象类型时依赖的也是reactive函数

3.用法:Proxy代理对象的数据键值对是和原数据对象的键值对一一对应的,在使用时可以直接使用 对象(接受返回值的对象).键名 的形式,ref对象会把数据参数对应到自己

value属性上,在模板里我们可以直接省略.value的形式,这看起来好像是“把源数据赋值给了ref类型的变量,可以直接在模板上使用这个ref类型的变量”

4.响应式原理:ref的响应式原理是依赖于Object.defineProperty( )的get( )和set( )而reactive的响应式原理是依赖于ES6中的Proxy。
  • 17
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值