【三.Vue3 响应式数据:ref与reactive全解析】

3. 响应式数据

3.1 ref创建_基本类型的响应式数据

  • ref作用:定义响应式变量

  • 返回值:返回RefImpl{}的实例对象,里面有value

  • 用法:刚开始要从vue中引入ref

<template>
        <div class="person">
          <h2>年龄:{{age}}</h2>
        </div>
      </template>
      
      <script lang="ts" setup name="Person">
        import {ref} from 'vue'
      
        let age = ref(18)
      
        function changeAge() {
          age.value += 1 
          console.log(age.value) 
        }
      </script>

注意:

  1. 对于let name = ref(18)来说,age不是响应式的,age.value是响应式的

  2. 模板里不用.value,JS里操作ref()包起来的东西一定需要.value

3.2 reactive创建_对象类型的响应式数据

  • reactive作用:定义响应式对象

    注意:基本类型不要用reactive,要用ref

  • 返回值:一个Proxy的实例对象
  • 刚开始要从vue中引入reactive
<template>
        <div class="person">
          <h2>汽车信息:一辆{{car.brand}}车,价值{{car.price}}</h2>
          <button @click="changePrice">修改汽车的价格</button>
          <br>
        </div>
      </template>
      
      <script lang="ts" setup name="Person">
        import {reactive} from 'vue'
      
        let car = reactive({brand:'奔驰',price:100})
      
        function changePrice(){
          car.price += 10
          console.log(car.price)
        }
      </script>

注意:reactive是深层次的响应式

3.3 ref创建_对象类型的响应式数据

  • 如果ref包的是对象类型,则ref实现响应式数据底层还是用reactive实现:被ref()包起来的东西变成了RefImpl{}的实例对象,但是RefImpl{}的实例对象里又包着Proxy{}的函数
  • 所以ref的处理对象类型也是是深层次的响应式

    3.4 ref对比reactive

  • 区别一:使用了reactive后可以改它里面的里面的某属性,但是不可以把整体改了,如果整体改了那么它的响应式就会消失
    • 错误例子:
<template>
          <div class="person">
            <button @click="changeCar">修改汽车</butto>
          </div>
        </template>
        
        <script lang="ts" setup name="Person">
          import {ref,reactive} from 'vue'
        
          let car = reactive({brand:'奔驰',price:100})
        
          function changeCar(){
            car = {brand:'奥拓',price:1} //这么写页面不更新的
            car = reactive({brand:'奥拓',price:1}) //这么写页面不更新的
          }
        </script>
  • 正确例子:解释:把新的brand:'奥拓'分配给原来的brand,把新的price:1分配给原来的price,相当于批量地把旧的数据替换成新的数据,所以对象的地址是不变的
<template>
          <div class="person">
            <button @click="changeCar">修改汽车</butto>
          </div>
        </template>
        
        <script lang="ts" setup name="Person">
          import {ref,reactive} from 'vue'
        
          let car = reactive({brand:'奔驰',price:100})
        
          function changeCar(){
            Object.assign(car,{brand:'奥拓',price:1})
          }
        </script>
> `Object.assign(car,{brand:'奥拓',price:1})`的解释:将源对象中的 `brand` 和 `price` 属性复制到 `car` 对象中。如果 `car` 对象原本就有 `brand` 或 `price` 属性,它们的值会被覆盖;如果没有,则会新增这些属性

使用了ref后可以改它里面的里面的某属性,也可以全部改了,它的响应式不会消失

注意:使用ref一定要有.value去改

  • 区别二:
    • 基本类型的响应式数据———>ref
    • 响应式对象且层级不深———>reactive
    • 响应式对象且层级较深———>ref
  • 区别三:ref创建的变量必须使用.value,但是reactive不用

3.5 toRefs与toRef

  • toRefs和toRef的作用:将一个响应式对象中解构的每一个属性都转换为ref对象
  • 解释:从一个响应式对象解构东西的时候,解构出来的相应的属性都不是响应式的,相当于拿了响应式的数据又创建一个新的地址来存放此数据
  • 区别:toRefs可以批量转换,toRef只能单个转换
  • 使用:toRefs前也要先从vue中引用
<template>
      <div class="person">
        <h2>姓名:{{person.name}}</h2>
        <h2>年龄:{{person.age}}{{nl}}</h2>
        <button @click="changeName">修改名字</button>
        <button @click="changeAge">修改年龄</button>
      </div>
    </template>
    
    <script lang="ts" setup name="Person">
      import {reactive,toRefs,toRef} from 'vue'
    
      let person = reactive({
        name:'张三',
        age:18
      })
    
      let {name,age} = toRefs(person)
    
      function changeName(){
        name.value += '~'
      }
      function changeAge(){
        age.value += 1
      }
    
    </script>

相当于

<template>
      <div class="person">
        <h2>姓名:{{person.name}}</h2>
        <h2>年龄:{{person.age}}{{nl}}</h2>
        <button @click="changeName">修改名字</button>
        <button @click="changeAge">修改年龄</button>
      </div>
    </template>
    
    <script lang="ts" setup name="Person">
      import {reactive,toRefs,toRef} from 'vue'
    
      let person = reactive({
        name:'张三',
        age:18
      })
    
      function changeName(){
        Person.name.value += '~'
      }
      function changeAge(){
        Person.age.value += 1
      }
    
    </script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值