搞懂vue3的ref、reactive、toRef、toRefs

首先需要明确这四个函数都是用于在 setup 中创造响应式变量的。
四个函数都需要从vue中导出: import {ref, reactive, toRef, toRefs} from 'vue'

总结:
reactive对比ref

从定义数据角度对比:

- ref用来定义基本类型数据

- reactive用来定义对象(或数组)类型数据

- 备注:ref也可以用来定义对象(或数组)类型数据,它内部会自动通过reactive转为代理对象;

从原理角度对比:

- ref通过Object.defineProperty()的get与set来实现响应式(数据劫持)

- reactive通过使用Proxy来实现响应式(数据劫持),并通过Reflect操作源对象内部的数据。

从使用角度对比

- ref定义的数据:js操作数据需要.value,模板中读取时不需要.value

- reactive定义的数据,操作与读取均不需要.value

toRef, toRefs

作用: 创建一个ref对象,其value值指向另一个对象中的某个属性

语法: const name = toRef(person, 'name')

应用: 要将响应式对象中的某个属性单独提供给外部使用时

扩展: toRefs与toRef功能一致,但可以批量创建多个ref对象,语法: toRefs(person)

 

分别举例:
ref使用
<template>
  <div class="demo">
    <h2>姓名: {{name}}</h2>
    <h2>年龄: {{age}}</h2>
    <h3>岗位: {{job.type}}</h3>
    <h3>工龄: {{job.workingAge}}</h3>
    <button @click="updateInfo()">更新</button>
  </div>
</template>
 
<script lang="ts">
import { defineComponent, ref } from 'vue'
 
export default defineComponent({
  setup () {
// 以下方式定义的是普通数据,非响应式数据
    // let name = '张三';
    // let age = 18;
    // let job = {
    //   type: 'web前端',
    //   workingAge: 8
    // }
    // function  updateInfo() {
    //   name = '李四';
    //   age = 20;
    //   console.log(name, age);
    // }
 
// 基本类型:ref生成一个引用对象,通过get/set做数据劫持,Ref(reference引用)Impl(implement实现)
    let name = ref('张三'); 
    let age = ref(18);
    console.log('name', name, age)
 
    // 对象类型,内部'求助'了vue3中的一个新函数reactive函数
    let job = ref({
      type: 'web前端',
      workingAge: 8
    })
    function  updateInfo() {
      // 注:模板里面不需要使用.value,模板解析时遇到 ref对象会自动读取.value
      console.log(name, age);
      name.value = '李四';
      age.value = 20;
      job.value.type = 'JAVA';
      job.value.workingAge = 10;
    }
    
    return {
      name,
      age,
      updateInfo,
      job
    }
  }
})
</script>

reactive:只用于创建引用类型数据的响应式,取值不用加.value return具体细节见代码注释

<template>
  <div class="demo">
    <h2>姓名: {{name}}</h2>
    <h3>岗位: {{job.type}}</h3>
    <h3 v-show="job.workingAge">工龄: {{job.workingAge}}</h3>
    <h3 v-show="job.age">年龄:{{job.age}}</h3>
    <button @click="updateInfo()">更新</button>
  </div>
</template>
 
<script lang="ts">
import { defineComponent, ref, reactive } from 'vue'
 
export default defineComponent({
  setup () {
    let name = ref('张三'); 
    let job: any = reactive({
      type: 'web前端',
      workingAge: 8
    })
    console.log('job', job)
    function  updateInfo() {
      name.value = '李四';
      job.type = 'JAVA';
      delete job.workingAge;// 删除工龄
      job.age = 18; // 增加年龄
      
    }
    // 返回一个对象(常用)
    return {
      name,
      job,
      updateInfo
    }
  }
})
</script>

toRef和toRefs

  setup () {
    let person = reactive({
      name: '张三',
      job: {
        j1: {
          age: 18
        }
      }
    })
 
    // 下面是几种方式的不同点描述
    return {
      person, // 直接return出去,模板中使用不能直接使用name 需要 person.name,比较麻烦
      name1: person.name, // 解构后模板中直接使用name,但是属性不再具有响应性
      name2: toRef(person, 'name'), // 通过toRef来转变成ref对象
      ...toRefs(person), // 批量转换成ref对象
    }
  }

 

posted @ 2022-11-29 12:43  爵岚  阅读(469)  评论(0编辑  收藏  举报