Vue.js 學習旅程Mile 10 – Event Handling 事件處理篇-2:Modifiers 修飾符


Posted by yuhantaiwan on 2020-05-03

修飾符 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

參考資料


#w3HexSchool #Vue #javascript







Related Posts

想要自學程式?七個自學程式設計正確的觀念和心態

想要自學程式?七個自學程式設計正確的觀念和心態

超讚 Deep Learning on 3D object detection 相關教學影片彙整

超讚 Deep Learning on 3D object detection 相關教學影片彙整

Web開發學習筆記15 — 呼叫堆疊、同步與非同步、Promise、Async/Await、Conditional ternary operator

Web開發學習筆記15 — 呼叫堆疊、同步與非同步、Promise、Async/Await、Conditional ternary operator


Comments