文章目錄
- Vue3-Composition-API(二)
-
- Reactive-API
-
- Reactive判斷的API
- toRefs
- toRef
- ref其他的API
- customRef
- computed
- 偵聽資料的變化
-
- watchEffect
- watchEffect的停止偵聽
- watchEffect清除副作用
- setup中使用ref
- watchEffect的執行時機
- 調整watchEffect的執行時機
- Watch的使用
-
- 偵聽單個資料源
- 偵聽多個資料源
- 偵聽響應式對象
- watch的選項
vue3筆記
vue3學習之旅–邂逅vue3-了解認識Vue3
vue3學習之旅–邂逅vue3-了解認識Vue3(二)
Vue3學習之旅–愛上Vue3–Vue3基礎文法(一)–以及vscode基本使用和快速生成代碼片段
Vue3學習之旅–愛上Vue3–Vue3的Options-API
vue3學習之旅–vue的表單和開發模式–元件化開發初識
Vue3學習之旅–初識webpack–webpack打包js,css,less等檔案以及相容性處理
Vue3學習之旅–之webpack基礎-進階–webpack5?拿來吧你!
vue3學習之旅–webpack5-babel整合sfc單檔案vue元件
Vue3學習之旅-webpack終章–熱部署(更新)–跨域代理?拿來吧你!
vue3學習之旅-Vue-CLI及其原理&尤大大新寵Vite-下一代前端開發建構工具Vite:拿來吧你!
Vue3學習之旅-之vue3元件化(一)—>父子元件通信
Vue3學習之旅–Vue3元件化開發(二)-非父子元件通信及元件插槽–細節太多建議反複觀看
Vue3學習之旅-Vue3元件化開發(三)-動态/異步元件-vue3生命周期-元件的v-model
Vue3學習之旅-Vue3過渡&動畫實作
Vue3學習之旅–Composition-API-入門篇
Vue3-Composition-API(二)
Reactive-API
Reactive判斷的API
-
isProxy
檢查對象是否是由 reactive 或 readonly建立的 proxy。
- isReactive
- 檢查對象是否是由 reactive建立的響應式代理:
- 如果該代理是 readonly 建的,但包裹了由 reactive 建立的另一個代理,它也會傳回 true;
- isReadonly
- 檢查對象是否是由 readonly 建立的隻讀代理。
- toRaw
- 傳回 reactive 或 readonly 代理的原始對象(不建議保留對原始對象的持久引用。請謹慎使用)。
- shallowReactive
- 建立一個響應式代理,它跟蹤其自身 property 的響應性,但不執行嵌套對象的深層響應式轉換 (深層還是原生對象)。
- shallowReadonly
- 建立一個 proxy,使其自身的 property 為隻讀,但不執行嵌套對象的深度隻讀轉換(深層還是可讀、可寫的)。
toRefs
如果我們使用ES6的解構文法,對reactive傳回的對象進行解構擷取值,那麼之後無論是修改結構後的變量,還是修改reactive 傳回的state對象,資料都不再是響應式的:
那麼有沒有辦法讓我們解構出來的屬性是響應式的呢?
- Vue為我們提供了一個toRefs的函數,可以将reactive傳回的對象中的屬性都轉成ref;
- 那麼我們再次進行解構出來的 name 和 age 本身都是 ref的;
這種做法相當于已經在**state.name和ref.value之間建立了 連結,**任何一個修改都會引起另外一個變化;
toRef
如果我們隻希望轉換一個reactive對象中的屬性為ref, 那麼可以使用toRef的方法:
// toRef函數,對其中一個屬性進行解構為ref響應式對象
/*
toRef(對象,'對象需要轉為ref的屬性')
*/
let { name } = info2;
let age = toRef(info2, "age");
ref其他的API
unref
如果我們想要擷取一個ref引用中的value,那麼也可以通過unref方法:
- 如果參數是一個 ref,則傳回内部值,否則傳回參數本身;
- 這是 val = isRef(val) ? val.value : val 的文法糖函數;
isRef
判斷值是否是一個ref對象。
shallowRef
建立一個淺層的ref對象;
triggerRef
手動觸發和 shallowRef 相關聯的副作用:(比如頁面的響應式重新整理,就是重新整理響應式資料以後的副作用)
customRef
建立一個自定義的ref,并對其依賴項跟蹤和更新觸發進行顯示控制:
它需要一個工廠函數,該函數接受 track 和 trigger 函數作為參數;并且應該傳回一個帶有 get 和 set 的對象;
這裡我們使用一個的案例:
對雙向綁定的屬性進行debounce**(節流)**的操作;
computed
在前面我們講解過計算屬性computed:當我們的某些屬性是依賴其他狀态時,我們可以使用計算屬性來處理
- 在前面的Options API中,我們是使用computed選項來完成的;
- 在Composition API中,我們可以在 setup 函數中使用 computed 方法來編寫一個計算屬性;
如何使用computed呢?
- 方式一:接收一個getter函數,并為 getter 函數傳回的值,傳回一個不變的 ref 對象;
- 方式二:接收一個具有 get 和 set 的對象,傳回一個可變的(可讀寫)ref 對象;
偵聽資料的變化
在前面的Options API中,我們可以通過watch選項來偵聽data或者props的資料變化,當資料變化時執行某一些 操作。
在Composition API中,我們可以使用watchEffect和watch來完成響應式資料的偵聽;
- watchEffect用于自動收集響應式資料的依賴;
- watch需要手動指定偵聽的資料源;
watchEffect
當偵聽到某些響應式資料變化時,我們希望執行某些操作,這個時候可以使用 watchEffect。
我們來看一個案例:
- 首先,watchEffect傳入的函數會被立即執行一次,并且在執行的過程中會收集依賴;
- 其次,隻有收集的依賴發生變化時,watchEffect傳入的函數才會再次執行;
watchEffect的停止偵聽
如果在發生某些情況下,我們希望停止偵聽,這個時候我們可以擷取watchEffect的傳回值函數,調用該函數即可。
比如在上面的案例中,我們age達到25的時候就停止偵聽:
watchEffect清除副作用
什麼是清除副作用呢?
- 比如在開發中我們需要在偵聽函數中執行網絡請求,但是在網絡請求還沒有達到的時候,我們停止了偵聽器, 或者偵聽器偵聽函數被再次執行了。
- 那麼上一次的網絡請求應該被取消掉,這個時候我們就可以清除上一次的副作用;
在我們給watchEffect傳入的函數被回調時,其實可以擷取到一個參數:onInvalidate
- 當副作用即将重新執行 或者 偵聽器被停止 時會執行該函數傳入的回調函數;
- 我們可以在傳入的回調函數中,執行一些清除工作;
setup中使用ref
在講解 watchEffect執行時機之前,我們先補充一個知識:在setup中如何使用ref或者元素或者元件?
其實非常簡單,我們隻需要定義一個ref對象,綁定到元素或者元件的ref屬性上即可;
watchEffect的執行時機
預設情況下,元件的更新會在副作用函數執行之前:
如果我們希望在副作用函數中擷取到元素,是否可行呢?
結果如上圖
我們會發現列印結果列印了兩次:
- 這是因為setup函數在執行時就會立即執行傳入的副作用函數,這個時候DOM并沒有挂載,是以列印為null;
- 而當DOM挂載時,會給title的ref對象指派新的值,副作用函數會再次執行,列印出來對應的元素;
調整watchEffect的執行時機
如果我們希望在第一次的時候就列印出來對應的元素呢?
- 這個時候我們需要改變副作用函數的執行時機;
- 它的預設值是pre,它會在元素 挂載 或者 更新 之前執行;
- 是以我們會先列印出來一個空的,當依賴的title發生改變時,就會再次執行一次,列印出元素;
我們可以設定副作用函數的執行時機:
flush 選項還接受 sync,這将強制效果始終同步觸發。然而,這是低效的,應該很少需要。
Watch的使用
watch的API完全等同于元件watch選項的Property:
- watch需要偵聽特定的資料源,并在回調函數中執行副作用;
- 預設情況下它是惰性的,隻有當被偵聽的源發生變化時才會執行回調;
與watchEffect的比較,watch允許我們:
- 懶執行副作用(第一次不會直接執行);
- 更具體的說明當哪些狀态發生變化時,觸發偵聽器的執行;
- 通路偵聽狀态變化前後的值;
偵聽單個資料源
watch偵聽函數的資料源有兩種類型:
偵聽器資料源可以是傳回值的 getter 函數,也可以直接是
ref
:
- 一個getter函數:但是該getter函數必須引用可響應式的對象(比如reactive或者ref);
- 直接寫入一個可響應式的對象,reactive或者ref(比較常用的是ref);
下面這種方式就偵聽失敗了,新值舊值是一樣的。
方式一
方式二
偵聽多個資料源
偵聽器還可以使用數組同時偵聽多個源:
偵聽響應式對象
如果我們希望偵聽一個數組或者對象,那麼可以使用一個getter函數,并且對可響應對象進行解構:
watch的選項
如果我們希望偵聽一個深層的偵聽,那麼依然需要設定 deep 為true:
也可以傳入 immediate 立即執行;
如果傳入的是一個reactive對象,預設情況就是會自動進行深度偵聽的,輸入擷取到的新值舊值都是還是同一個對象
設定深度偵聽