實務上有些需求只希望 User 只能 Click Button 一次,之後任何 Click 都忽略不計,此時可使用 once
Event Modifier 達成。
Version
Vue 3.0.11
Vanilla JavaScript
無論 +
被按幾次,count
都只遞增到 1
就停止。
<template lang='pug'>
button(@click='onClick') +
span {{ count }}
</template>
<script setup>
ref: isClicked = false
ref: count = 0
let onClick = () => {
if (isClicked) return
isClicked = true
count++
}
</script>
第 7 行
ref: count = 0
ref: isClicked = false
isClicked
:判斷 button 是否第一次被 clickcount
:負責遞增 counter 與顯示
10 行
let onClick = () => {
if (isClicked) return
isClicked = true
count++
}
首先判斷 isClicked
state 是否為 true
,若已經被 click 過則 return
結束。
Once Event Modifier
結果不變,但使用 once
event modifier 改寫。
<template lang='pug'>
button(@click.once='onClick') +
span {{ count }}
</template>
<script setup>
ref: count = 0
let onClick = () => count++
</script>
第 2 行
button(@click.once='onClick') +
在 click
之後加上 once
event modifier 之後,onClick()
只會被 trigger 一次,因此不必再搭配 isClicked
state 判斷。
第 9 行
let onClick = () => count++
只需實現對 count
state 遞增即可,不用判斷是否已經被 click 過。
Point-free
結果不變,但使用 Point-free 改寫。
<template lang='pug'>
button(@click.once='onClick') +
span {{ count }}
</template>
<script setup>
import { ref } from 'vue'
import { read, write } from 'vue3-fp'
import { pipe, inc } from 'ramda'
let count = ref(0)
let onClick = pipe(
read(count),
inc,
write(count)
)
</script>
13 行
let onClick = pipe(
read(count),
inc,
write(count)
)
使用 pipe()
組合 onClick()
:
read(count)
:讀取count
stateinc
:對值遞增write(count)
:寫入count
state
Conclusion
- 若使用 Vanilla JavaScript 實現,還需要搭配另外一個 state 控制是否 click 過
- 使用
once
event modifier 讓 HTML 意圖更明顯,且 JavaScript 也不必另外維護 state