ref再複習
寫了一陣子 VUE,也用了一陣子的 ref(),結果看了 Alex 的直播才發現自己和 ref() 有點陌生,回頭去好好讀了 VUE3 的官方文件,整理了一下筆記,方便回頭複習。
ref 重點整理
- ref() 會將傳入參數的值轉換為帶有 .value 屬性的 ref 物件
- 如果 ref()放入的是物件,則 .value 屬性的值是proxy物件
- ref() 是 refimpl 的物件
- ref() 的.value 是響應式的,當值為物件時,會用 reactive() 轉換 .value
- ref() 的參數如果放入物件型別,可以響應式的替換整個物件
- ref() 被傳遞給函式或是解構時,不會失去響應性
- ref() 讓我們能夠創造對任意值得引用 (reference),並在不失去響應性的前提下傳遞這些引用
- ref() 在 template渲染 上下文頂層屬性時才會自動解包
- 當一個 ref 被放入reactive() 物件中,作為屬性被訪問或更改時,會自動解包
- 如果將一個新的 ref() 賦值給一個已經有 ref 的屬性,那它會替換舊的 ref
ref() 會將傳入參數的值轉換為帶有 .value 屬性的 ref 物件
在 VUE 裡面要使用 ref(),作法是在 () 括號中放入 基本型別的字串、數字或是布林值,也可以放入陣列或是物件。
ref()的樣子看起來就是一個函式,() 括號中放入的就是參數,參數會變成帶有 .value 的 ref 物件。
參數可以傳入基本型別的字串、數字或是布林值,也可以放入陣列或是物件。
以下面 VUE 官網的例子來說,console.log(count)
得出一個 { value: 0 }
的物件,因此要取得 count
的值必須使用 count.value
。
ref() 的.value 是響應式的
ref() 的.value 是響應式的,當值為物件時,會用 reactive() 轉換為 .value,所以裡面運作的是proxy 機制,但如果是基本型別的話則否。
在 SFC 的 <script>
區塊要透過 .value 取值,而在<template>
模板中取用 ref() 不需要加上 .value。
ref() 的參數如果放入物件型別,可以響應式的替換整個物件
ref() 被傳遞給函式或是解構時,不會失去響應性
ref() 讓我們能夠創造對任意值的參考 (reference),並在不失去響應性的前提下傳遞這些參考。
甚麼是「解包」
「解包」這兩個字其實就是英文的 「unwrap」,指的是當在 <template>
中引用 ref 的頂層屬性不需要使用 .value。
頂層屬性的 ref 才能自動解包
也就是如果是在物件的屬性中包入 ref() 雖然能傳遞計算後的最終值,但是如果在模板中做處理效果會不如預期。例如下面的範例,{{ object.foo + 1 }}
會變成 [object Object]1
。
但是如果是在函式中做運算,則可以正常運作。
由上面的範例也可以看到,當 ref()作為物件的屬性時,即使經過解構,判斷 object.foo === foo
仍然為 true,指向相同的參考。
ref() 在 reactive() 作為屬性解包
当一个 ref 被嵌套在一个响应式对象中,作为属性被访问或更改时,它会自动解包,因此会表现得和一般的属性一样:
當 ref() 作為一個 reactive()物件的屬性被操作時,它會自動解包,表現和一般屬性一樣:
一個已經是 ref() 的常數可以被新的 ref() 賦值
俗話說:「只見新人笑,不見舊人哭」,如果一個常數已經被某個 ref()賦值,仍然可以拿一個新的 ref() 賦值給它,這時這個常數就會指向新的 ref()。