1. 程式人生 > 其它 >搞懂vue3的ref、reactive、toRef、toRefs

搞懂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物件
    }
  }