修飾符 Modifiers
修飾符依照功能可以分為下面兩類:
- 事件修飾符(Event Modifiers):事件相關的處理或設定。
- 按鍵修飾符(Key Modifiers):鍵盤或是按鈕的事件中觸發的按鍵設定。
事件修飾符 (Event Modifiers)
Vue 提供一些常用處理的修飾符,讓我們可以直接設定在屬性上,除了減少程式碼量外,最大的目的是讓方法盡量只是單純處理邏輯,而不用多去擔心相關的 DOM 處理。
.stop
: 呼叫 event.stopPropagation(),停止觸發上層 DOM 元素事件.prevent
: 呼叫 event.preventDefault(),避免瀏覽器預設行為.capture
: 不管觸發事件的目標是否是下層, 設定capture
的事件一定會先觸發.self
: 僅觸發自己範圍的事件,不包含子層
.stop
修飾符
.stop
修飾符會叫用 event.stopPropagation()
,stopPropagation
方法會停止事件的冒泡。
在預設的情況下,觸發了下層 DOM 元素的事件後,會往上叫用其他 DOM 元素的事件,可是當加上 stopPropagation
後,就只會到目前的事件為止,不會往父層觸發。
Js 預設的事件傳遞方向為向上冒泡(event bubbling),也就是從內到外執行。
<div class="outer" @click="alert('outer, none-once, default')">
outer
<div class="middle" target="_blank" @click="alert('middle, none-capture, default')">
middle
<div class="inner" target="_blank" @click.stop="alert('inner, not trigger upper except capture')">
inner, stopPropagation(not trigger upper except capture)
</div>
</div>
</div>
當按下 inner 後, middle 跟 outer 的事件會因為 inner 的 click 加入了 .stop
修飾符而不被觸發。
.prevent
修飾符
.prevent
修飾符會叫用 event.preventDefault()
,preventDefault
會停止瀏覽器的預設行為。例如: checkbox 的勾選/取消勾選行為、 form 的 submit 送出表單行為等,都會因為 preventDefault
而沒有觸發。
<a class="inner" href="https://developer.mozilla.org/" target="_blank"
@click.prevent="alert('inner2, none-passive, default, not open new page')">
inner2, none-passive & preventDefault(not open new page)
</a>
原本按下超連結後會直接開啟 href 設定的頁面,可是因為 click 事件有設定 .prevent
修飾符,所以不會開啟連結。
.capture
修飾符
不管觸發事件的 DOM 元素是誰,使用 .capture
修飾符的事件會優先觸發。
<div class="middle" target="_blank" @click.capture="alert('middle, capture')" @click="alert('middle, none-capture, default')">
middle, capture & none-capture & self
<a class="inner1" href="https://www.mozilla.org" target="_blank" @click="alert('inner1, passive, open new page')">
inner1, passive & preventDefault(which is not allowed)
</a>
</div>
當按下 inner1 時,可以看到 alert('middle, capture') 先被觸發,再來是 alert('inner1, passive, open new page') ,最後才是 alert('middle, none-capture, default') ,由此現象可知 .capture
會打破由內而外的事件傳遞規則,先行觸發。
關於捕獲與冒泡事件,可參考以下文章:
.self
修飾符
.self
修飾符只會觸發自己範圍內的事件,不包含子元素。
<div class="middle" target="_blank" @click.self="alert('middle, self')">
middle, self
<div class="inner4" target="_blank" @click="alert('inner4')">
inner4
</div>
</div>
.once
修飾符
.once
修飾符使事件只會觸發一次。
<div class="outer" @click.once="alert('outer, once')" @click="alert('outer, none-once, default')">
outer
</div>
當點擊第一次的時候兩個事件都會被觸發,可是之後都只有沒有 .once
修飾符的事件會被觸發。
.passive
修飾符
.passive
修飾符會無視 event.preventDefault()
的功能,只要加上此修飾符就一定會觸發瀏覽器的預設行為。
不要把 .passive
和 .prevent
一起使用,因為 .prevent
將會被忽略。
<a class="inner1" href="https://www.mozilla.org" target="_blank" @click.passive.prevent="alert('inner1, passive, open new page')">
inner1, passive & preventDefault(which is not allowed)
</a>
由於 .passive
會使 preventDefault
無效,所以就算在 .passive
後面加上 .prevent
還是會開啟連結頁面。
修飾符的順序
使用修飾符時,順序很重要;相應的程式碼會以同樣的順序產生。因此,用 v-on:click.prevent.self
會阻止所有的點擊,而 v-on:click.self.prevent
只會阻止對元素自身的點擊。
按鍵修飾符(Key Modifiers)
監聽鍵盤事件的特定鍵值。
注意:keyCode 的事件用法已經被廢棄了並可能不會被最新的瀏覽器支持。
按鍵值
只要是在 KeyboardEvent.key 上的按鍵名稱都可以用 kebab-case 的方式設定在修飾符上。
<input v-on:keyup.page-down="onPageDown">
Vue 會在函數中使用 $event.key === 'PageDown' 判斷式決定是否為目標按鈕
按鍵碼別名
為了在必要的情況下支持舊瀏覽器,Vue 提供了絕大多數常用的按鍵碼的別名:
.enter
.tab
.delete
(Delete 跟 Backspace 按鍵都會觸發).esc
.space
.up
.down
.left
.right
自定義按鍵修飾符別名
在 Vue.config.KeyCodes
物件中設定自定義的別名:
- key : 別名名稱,不可使用 camelCase 設定名稱,但是可以使用雙引號綁定 kebab-case 的別名。
- value : 對應的按鍵編號,可以使用陣列同時綁定多個編號。
<div id="app">
<input @keyup.f1="what='keyup.f1'" @keyup.up="what='keyup.up'" @keyup.insert-mode="what='keyup.insert-mode'" />
<span>You trigger event by <strong>{{what}}</strong></span>
</div>
Vue.config.keyCodes = {
f1: 112, // f1
up: [38, 87], // 數字鍵 8 跟 w
// insertMode: 73, // won't work
"insert-mode": 73 // i
};
系統修飾鍵 (System Modifier Keys)
僅在按下相應按鍵時才觸發滑鼠或鍵盤事件的監聽器
.ctrl
.alt
.shift
.meta
<!-- Alt + C -->
<input v-on:keyup.alt.67="clear">
<!-- Ctrl + Click -->
<div v-on:click.ctrl="doSomething">Do something</div>
與常規按鍵不同之處
使用系統修飾鍵設定修飾符的 keyup
事件只有在該系統鍵按住的狀態下才會觸發事件,例如:
<div id="app">
<input"
@keyup.ctrl="what='keyup.ctrl'"
@keyup.17="what='keyup.17'"
/>
<span>You trigger event by <strong>{{what}}</strong></span>
</div>
@keyup.ctrl
: 要在按住 Ctrl 鍵的狀況下釋放其他按紐才會觸發。@keyup.17
: 只要釋放 Ctrl 按鈕就會觸發。
.exact
修飾符
設定 .exact
修飾符代表一定要完全符合系統修飾鍵的設定才會觸發事件
<!-- 即使 Alt 或 Shift 被一同按下時也會觸發 -->
<button v-on:click.ctrl="onClick">A</button>
<!-- 有且只有 Ctrl 被按下的時候才觸發 -->
<button v-on:click.ctrl.exact="onCtrlClick">A</button>
<!-- 沒有任何系統修飾符被按下的時候才觸發 -->
<button v-on:click.exact="onClick">A</button>
滑鼠按鍵修飾符 (Mouse Button Modifiers)
Vue 提供左中右三個滑鼠按鍵的修飾符
.left
.right
.middle