首先我們先介紹他們是什麼???
在 Vue 中,toRef
和toRefs
都是用於處理響應式資料的工具函式。
toRefs
主要用於將一個響應式物件轉換為一組響應式引用物件。這樣做的好處在於,當你需要解構一個響應式物件時,使用toRefs
可以確保解構後的屬性仍然保持響應式。toRef
允許從一個已有的響應式物件中建立一個對特定屬性的響應式引用。這個引用會保持與源物件屬性的響應式連線,即當源物件的屬性值發生變化時,透過toRef
建立的引用也會同步更新。
上面的圖片是Vue
官方文件給出的解釋,toRefs的實現一定程度是基於toRef上的,下面我們一起透過程式碼例項來理解這兩個APi吧!
🐟toRefs
<template> <div> <h2> 姓名:{{ perosn.name }}</h2> <h2> 年齡:{{ person.age }}</h2> <button @click="changeName">增加~</button> <button @click="changeAge">加一</button> </div> </template> <script setup> import { reactive } from 'vue' let person = reactive({ name: '張三', age: 18 }) const changeAge = () => { person.age += 1 } const changeName = () => { person.name += '!' } </script> <style scoped></style>
這段函式定義了一個含有屬性name
和age
的Person
物件,並且定義了兩個button去修改name
和age
. 如果在這個時候你想使用解構賦值,將person中的name和age提取出來,
let { name, age } = person
是否這個時候我們就可以透過解構出來的age和person,不需要再使用字首Person去呼叫了,
<template> <div> <h2> 姓名:{{ name }}</h2> <h2> 年齡:{{ age }}</h2> <button @click="changeName">增加~</button> <button @click="changeAge">加一</button> </div> </template> <script setup> import { ref, reactive } from 'vue' let person = reactive({ name: '張三', age: 18 }) let { name, age } = person const changeAge = () => { age += 1 console.log(age); } const changeName = () => { name += '!' console.log(name); } </script> <style scoped></style>
你會發現檢視介面並沒有更新,但是我在函式裡寫的console.log(age)
和 console.log(name)
他們的輸出會隨著函式的呼叫而改變,說明age
和name
並不是沒有改變,而是person.age``person.name
沒有改變,因為person
纔是響應式物件,而當對一個物件進行解構賦值
時,會建立新的變數
來引用物件的屬性值
。如果修改這些新變數的值
,不會直接影響原始物件
。所以就能很好的解釋為什麼 age,name
的值明明改變了但是為什麼檢視介面不更新的原因.
這個時候Vue就提供api
讓我們去解決這個問題 首先我們介紹toRefs,看下面一段程式碼
<template> <div> <h2> 姓名:{{ name }}</h2> <h2> 年齡:{{ age }}</h2> <button @click="changeName">增加~</button> <button @click="changeAge">加一</button> </div> </template> <script setup> import { toRefs, reactive } from 'vue' let person = reactive({ name: '張三', age: 18 }) let { name, age } = toRefs(person) const changeAge = () => { age.value += 1 console.log(age); } const changeName = () => { name.value += '!' console.log(name); } </script> <style scoped></style>
我們在解構賦值的時候給person
加上了toRefs
,顧名思義,toRefs
就是讓解構出來的值變成ref
所定義的響應式資料,所以需要加上value
去修改他的值,console.log()
出來的age
和name
也驗證了我們的想法
我們把 let { name, age } = toRefs(person)
這行改為 let x = toRefs(person)
,然後輸出一下 x
這個時候我們就可以理解上面說將一個響應式物件轉換為一組響應式引用物件
了
🐟toRef
接下來我們介紹一下toRef,toRefs
是把person
這個響應式物件所有的key:value
一次性都取出來,賦予響應式能力,toRef
比他少了一個s
,所以他是建立一個對特定屬性的響應式引用,老規矩還是來看一段程式碼
例如,假設有一個響應式物件
person = reactive({ name: '張三', age: 18 })
,可以使用const nameRef = toRef(person, 'name')
建立一個對person
物件中name
屬性的引用。
<template> <div> <p>姓名:{{ nameRef.value }}</p> <p>年齡:{{ person.age }}</p> <button @click="changeName">修改姓名</button> </div> </template> <script setup> import { reactive, toRef } from 'vue'; const person = reactive({ name: '張三', age: 18 }); const nameRef = toRef(person, 'name'); const changeName = () => { nameRef.value = '李四'; }; </script>
簡單來說就是toRef
適合建立單個屬性的響應式引用,這個引用是響應式的,當源物件的該屬性發生變化時,透過toRef
建立的引用也會同步更新。
🐟END
他們兩兄弟適用於保持解構後的響應式,一個作用是建立一個對源響應式物件特定屬性的響應式引用,另一個是作用是建立一個對源響應式物件特定屬性的響應式引用,大家可以透過字尾s
很好的去區別,他們還可以取到簡化程式碼結構的作用