搞懂vue3的ref、reactive、toRef、toRefs
阿新 • • 發佈:2022-11-29
首先需要明確這四個函式都是用於在 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物件
}
}