watch 前先小等一下

鱈魚
發佈於Vue
閱讀時間約 4 分鐘
raw-image


先說結論:

watch 不是不能用,而是在使用 watch 之前,先想想有沒有其他方案,真的沒有才用 watch。


千萬不要為了一時方便讓元件裡滿滿的 watch,因為容易產生難以追蹤的副作用,會讓資料流更加複雜。


口說無憑,讓我們舉個栗子 (。・∀・)ノ🌰。


考慮一個簡單的元件,可以提供數值資料:

<script setup lang="ts">
interface Props {
modelValue?: string | number;
}
const props = withDefaults(defineProps<Props>(), {
modelValue: 0,
});

const emit = defineEmits<{
(e: 'update:modelValue', value: number): void;
}>();

const numberValue = ref(props.modelValue);

watch(() => props.modelValue, (value) => {
numberValue.value = parseFloat(value);
});
</script>

你可能會想問:「阿不是說能不用就不要用,怎麼開場就有 watch?」


這是因為除了 watch 以外,沒有其他方法可以在元件內得知 props.modelValue 發生變更,所以此部分可以使用 watch。

(或是請大家指教其他方法。(. ❛ ᴗ ❛.))。


以上程式已經將 props.modelValue 數值同步至 numberValue 中,現在只差將 numberValue 數值 emit 出去部分,直覺上可能會這樣寫:

<script setup lang="ts">
...

watch(numberValue, (value) => {
emit('update:modelValue', parseFloat(value));
});
</script>

在簡單的例子中,這樣寫不會有太大問題,但是若 numberValue 資料較為複雜(例如深層物件、矩陣等等)或者是資料耦合其他邏輯時,這樣寫可能會導致 watch 無限呼叫或其他難以追蹤的副作用。


一般情況下,我們應該可以直接知道 numberValue 的變化來源。

(如果沒辦法得知,應該重新仔細思考設計)


如果是 input 的話,我們可以從 @change 事件得知數值變化,所以此例子可以不使用 watch,結果可能會這樣:

<script setup lang="ts">
...

function handleUpdate() {
emit('update:modelValue', parseFloat(numberValue.value));
}

// 或是這樣
function handleUpdate(value: string) {
emit('update:modelValue', parseFloat(value));
}
</script>

也就是在明確的資料流中呼叫 emit。


最後讓我們總結一下。(。・∀・)ノ゙


在設計元件時,請讓資料流盡可能單向且單純,以免寫得時候很爽,除錯的時候火葬場。


例如 Vue v-model 的雙向綁定就是一個經典的例子。


大家應該都是知道 v-model 其實是個語法糖,程式碼很簡單時使用 v-model 容易且簡單。


但是一但資料開始複雜時,就會建議拆成 :model-value@update:modelValue 處理(也就是把原本的雙向資料流,拆成兩個單向資料流),彈性更高更可靠。( •̀ ω •́ )✧

(一時想不到有甚麼好例子,有想到再來分享,或是請大家幫忙補充補充。(´▽`ʃ♡ƪ))


但是如果發現元件內有很多「只能用 watch 才能處理的邏輯」,那就表示你可能耦合了太多邏輯和副作用在單一元件內了,請思考拆分元件、重構或者重新探討元件設計了。

9會員
10內容數
各種鱈魚滾鍵盤的雜紀
留言0
查看全部
發表第一個留言支持創作者!
你可能也想看
創作者要怎麼好好休息 + 避免工作過量?《黑貓創作報#4》午安,最近累不累? 這篇不是虛假的關心。而是《黑貓創作報》發行以來可能最重要的一篇。 是的,我們這篇講怎麼補充能量,也就是怎麼休息。
Thumbnail
avatar
黑貓老師
2024-06-29
防曬產品係數測試報告彙整(2024年)從2014年起,自己對於市售防曬產品的效能產生了濃厚的興趣。因為當時候發現不少產品的防曬係數其實標示是有問題的,像是原本應該是人體測試的SPF與PA數值,實際上沒有做,只用機器測試的數據來充當,但這兩者卻有很大的差異。像是防曬係數其實有強度、廣度與平均度三個面向需要一起判斷,但多數廠商並沒有完整標示
Thumbnail
avatar
邱品齊皮膚科醫師
2023-04-27
Apple Watch 在美禁售風波,到底發生什麼事?蘋果公司近年Apple Watch多主打健康監測功能,包含心電圖、血氧監測等。 但因「血氧監測」功能,蘋果面臨專利侵權挑戰,導致在美國可能無法銷售具備血氧功能的Apple Watch。這篇文章梳理了此次專利侵權風波的細節及最終決定。
Thumbnail
avatar
糰子律師 Attorney Dango
2023-12-29
Redmi Watch 4登場!HyperOS搭載、大屏AMOLED,搶攻智能手錶市場!最近在中國市場推出的Redmi Watch 4不僅是一款標榜高性價比的智能手錶,還是首款搭載最新發表的小米HyperOS的手錶產品。它搭載比Apple Watch Ultra更大、解像度為390 x 450的1.97吋AMOLED LTPS屏幕,支援60Hz更新率、Always-On顯示和600ni
Thumbnail
avatar
VC
2023-12-01
【省錢】Apple Watch S8, S9, Ultra 2 怎麼買 最便宜 最划算還在苦苦尋找,在哪邊購買 Apple Watch ,才能最省錢,最便宜嗎? 一堆「福利品」的低價拆封品,充斥在網路購物平台上 有一些品項,還是不肖業者推出的「整新品」,還得逐一查證比對,以免踩雷 不過就是買 Apple Watch,要搞這麼累嗎? 身邊總有朋友,會問筆者: 如何購買 Apple Wa
Thumbnail
avatar
Dash
2023-05-06
Watch UFC 287 Live Stream Reddit On Tv Channel蒙克正在重新开放吗? St. Pete Eatery 挑逗社交媒体粉丝 标志性的圣彼得堡餐厅 Munch’s Restaurant & Sundries 对其计划保持沉默,但承诺“这家餐厅会很大”。 Tiffany Razzano 的头像 蒂芙尼·拉扎诺, 补丁人员 已验证补丁人员徽章 美国东部时间
avatar
talara1538
2023-04-07
雜談|Watch out!it's OBSYDIA——淺聊Nijisanji EN④雖然儘管現在都知道OBSYDIA的三人混沌度加起來遠遠不及LazuLight,但這首《Black Out》裡面歌詞確實也有一句「“センパイ?” ( Senpai )」,顯示了OBSYDIA她們其實就是小惡魔後輩那樣的定位。她們的囂張之所以看起來會可愛,是因為觀眾知道前輩不會讓他們永遠這麼囂張的。
Thumbnail
avatar
涼柚
2022-02-23
Watch Out 精神中國羽毛球選手為抗衡對手的「聲音騷擾」,出奇制勝,以狂飆「我操!」來壓倒對手晉級,實力可見一斑,須知道如眼鏡可減球速,聲波更可改變球道,就算在這方面沒有足夠數據支持,都無礙國人的理解,此所謂「戰狼戰術」⋯⋯
Thumbnail
avatar
鄭子遴
2021-08-28
從健身到健康,從個人到家庭 -淺談Apple Watch的產品定位越來越習慣Tim Cook每次介紹Apple Watch時,都要提一下在健康上幫助了多少人,其實這跟Apple Watch的產品定位息息相關。
Thumbnail
avatar
Porter
2020-09-26
最強都市奇幻,沒有之一:《Night Watch》《Night Watch》獨立來看是非常出色的都市奇幻作品,而作為系列的首部曲,更完成了吸引讀者看下去的重要任務。
Thumbnail
avatar
笑耶
2020-09-14
Watch this before you vote in 2020This is Michael Moore's film 'Fahrenheit 11 / 9'. I implore you to watch this in its entirety before voting in 2020 in the USA. Please. I don't give
avatar
尚盧之劍
2020-05-24
watch 與「望;朢;望觀;朢察;朢視;望時辰;望時手環;望時箍;腕錶;望錶;錶」等橋接完整標題:watch 與「望」、「朢」或「望觀」、「朢察」、「朢勘」、「朢監」、「朢視」或「望時查」、「望時辰」、「朢時間」、「望時刻衡」或「望時手環」、「望時箍」、「腕錶」或「望錶」、「朢錶」 、「錶」等的轉換密碼
Thumbnail
avatar
羅聖爾
2019-10-03