挑戰只會讓我變得更強!今天,我不僅提升了技術,還掌握了全新的技能:VueUse 中的 useVModel!在程世社季子的眼中,VueUse 就像一條盤繞的龍,而我終於能從這龍的力量中汲取力量。不再是初學者的我,現在已經能夠輕鬆處理元件之間的資料變化。我知道,這只是邁向巔峰的第一步,還有更強大的敵人等待著我。程世社季子,我一定會讓你重新看到我脫胎換骨的模樣,等著吧!
#挽回愛情的第六天
useVModel
是 VueUse 中強大的函式之一,它幫助我們更輕鬆地在組件之間進行雙向綁定,特別是在父子組件的資料同步時。這篇文章將從其結構、動機以及實際應用等方面,詳細介紹 useVModel
函式。
useVModel
?在 Vue 中,組件的雙向綁定通常透過 v-model
來完成,這對於父子組件之間的資料同步非常方便。然而,useVModel
函式進一步抽象化了這個過程,並提供了更多的靈活性。使用 useVModel
,我們可以更清楚地控制父子組件之間的資料流,並能根據需求對資料進行轉換或處理。
如果對於雙向綁定不是那麼明白,可以看看這篇(裡面的圖解蠻好的)
假設我們有一個父組件,它將數據通過 v-model
傳遞給子組件,並希望子組件能更新這些數據。在標準的 Vue 中,這需要父組件通過 v-model
綁定一個 prop
,然後子組件發出相應的 emit
事件,將更新後的資料傳回父組件。這個流程很常見,但隨著應用規模的增大或場景的複雜化,可能會變得難以管理。
useVModel
的設計初衷就是為了簡化這些資料的雙向綁定,讓開發者可以更靈活地控制雙向資料流,同時保持 Vue 的響應式優勢。
範例 1:使用 passive: false 的簡單雙向綁定
範例 2:使用 passive: true 進行自定義雙向綁定和驗證
useVModel
的結構解析useVModel
的基本使用方式首先,我們來看看 useVModel
的使用範例:
const model = useVModel(props, 'modelValue', emit)
這段程式碼實現了從父組件到子組件的數據雙向綁定。useVModel
接收三個主要參數:
props
:從父組件傳遞下來的 props
對象。modelValue
:這是 v-model
的對應綁定鍵,也就是 props
中的屬性名。emit
:用於子組件向父組件發出更新事件的方法。在這個例子中,useVModel
幫助我們在子組件中管理 modelValue
的數據變更,並自動將其傳回給父組件。
v-model
的使用Vue 3 支援自定義 v-model
綁定的屬性名,而 useVModel
也允許我們輕鬆地實現這一點。例如,如果我們的 v-model
綁定名不是默認的 modelValue
,可以這樣使用:
const customModel = useVModel(props, 'customValue', emit)
在這裡,我們將 v-model
綁定到 customValue
,而不是默認的 modelValue
。
useVModel
的函數實作讓我們簡單了解一下 useVModel
的原始碼結構,為了好理解,筆者將原始碼簡化,來理解它如何實現這個功能:
import { computed, WritableComputedRef } from 'vue-demi'
export function useVModel<T>(
props: any,
key: string,
emit: (event: string, ...args: any[]) => void,
options: { passive?: boolean; eventName?: string } = {},
): WritableComputedRef<T> {
return computed<T>({
get() {
return props[key] as T
},
set(value) {
if (options.passive)
return
emit(options.eventName || `update:${key}`, value)
},
})
}
computed
函數的應用useVModel
的核心在於使用了 computed
函數來生成一個可寫的 ref
。computed
函數幫助我們自動監聽 props
中對應鍵的變化,並在它發生變化時進行更新。
get
函數:這個函數返回 props[key]
的當前值,也就是從父組件傳來的資料。set
函數:當我們在子組件中更新 model
時,set
函數會觸發 emit
,並將更新的值傳回父組件。options
參數useVModel
還提供了一個選擇性參數 options
,讓我們可以控制一些額外的行為:
passive
:如果設置為 true
,則子組件的變化不會傳回父組件,這在某些情境下很有用,比如當我們希望避免不必要的雙向同步。eventName
:我們可以自定義發出事件的名稱,默認情況下,事件名是 update:${key}
,這與 Vue 的 v-model
規範一致。v-model
雙向綁定假設我們有一個輸入框組件,它通過 v-model
與父組件的數據進行雙向綁定。使用 useVModel
可以讓這個過程更加直觀:
父組件:
<template>
<CustomInput v-model="inputValue" />
</template>
<script setup>
import { ref } from 'vue'
const inputValue = ref('')
</script>
子組件:
<template>
<input v-model="model" />
</template>
<script setup>
import { useVModel } from '@vueuse/core'
const props = defineProps(['modelValue'])
const emit = defineEmits(['update:modelValue'])
const model = useVModel(props, 'modelValue', emit)
</script>
在這個範例中,父組件的 inputValue
會自動與子組件的輸入框綁定,並且隨著輸入框的變化,inputValue
也會自動更新。
useVModel
是一個極具實用性的函式,特別適合用於處理 Vue 中的雙向綁定場景。它讓我們能夠輕鬆地控制父子組件的資料同步,並提供了更多的靈活性。透過使用 useVModel
,我們可以避免手動處理 emit
事件和 prop
的變更,大大簡化了程式碼邏輯。
這個函式展示了 VueUse 的強大之處:即使是簡單的功能,也能通過精心設計的工具函數,讓開發者的工作更加高效、便捷。