iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 4
0
自我挑戰組

跟 VueJS 認識的30天系列 第 8

[DAY08]跟 Vue.js 認識的3天 - Vue 的事件監聽

在 JS 中有監聽器 addeventListener ,而 Vue 也有自己一套 DOM 元素監聽器的指令 v-on , Vue 也配置了幾個修飾符來替代像是 preventDefault()stopPropagation() 等等的。

v-on 指令

執行簡單事件

<!--v-on:事件=執行事件-->
<button type="button" v-on:click="count++">數字加1</button>

v-on:click="count++" 就是指當 <button> 元素發生 click 事件,就執行 count++

執行複雜事件

  • 方法一:綁定方法

    <!--v-on:事件=執行事件-->
    <button type="button" v-on:click="greet">數字加1</button>
    <script>
    const vm = new Vue({
      el:'#vm',
      data:{
        userName:'Celeste'
      },
      methods:{
        greet(){
          alert(`Hello ${this.userName}`)
        }
      }
    })
    </script>
    

    把複雜的事件處理方法寫在 methods 裡,在讓 v-on 接收這個方法,如 greet ,在接收時,該方法並不需要加上 ()
    當事件(click)發生時,執行的方法預設有 event 物件,所以無須將 event 設為參數。

  • 方法二:調用方法

    Vue 提供 $event 屬性,可以用來取得 DOM event 物件的值。

    <!--v-on:事件=執行事件-->
    <button type="button" v-on:click="greet2('Celeste',$event)">數字加1</button>
    <script>
    const vm = new Vue({
      el:'#vm',
      methods:{
        greet2(name,event){
          alert(`Hello ${name}`)
          console.log(event)
        }
      }
    })
    </script>
    
    <!--v-on:事件=執行事件-->
    <button type="button" v-on:click="greet">數字加1</button>
    <script>
    const vm = new Vue({
      el:'#vm',
      data:{
        userName:'Celeste'
      },
      methods:{
        greet(){
          alert(`Hello ${this.userName}`)
        }
      }
    })
    </script>
    

加入事件修飾符的 v-on 指令

在 JS 中,可以透過一些方法來阻止一些預設行為,像是 event.preventDefault()event.stopPropagation() 或是改變事件傳遞的階段,而 Vue 透過加入修飾符也能達到相同的作用。

Vue 提供的修飾符:

  • .stop
    .stop 跟 JS 裡 event.stopPropagation() 目的相同,阻止後續的事件傳遞。

    <div class="changeTarget" v-on:click.stop="changeTarget('div')">
      <button type="button" v-on:click.stop="changeTarget('button')">changeTarget</button>
    </div>
    

    在沒有 .stop 的情況,如果點擊 <button> ,則上層 <div><button>皆會觸發 changeTarget(),這是因為事件的傳遞預設為 Bubbling ,所以在觸發 changeTarget('button') 後,會接續觸發 changeTarget('div') ,而修飾符 .stop 就是當第一個事件執行後,後續的冒泡事件又或是捕獲事件就會被阻止。

  • .prevent
    .prevent 跟 JS 裡 event.preventDefault() 目的相同,阻止元素的預設行為,像是 <a><button> 的預設行為會導致頁面跳轉或重整。

    <a href="https://www.google.com/" target="_blank" v-on:click.prevent="changeTarget('a')" >changeTarget</a>
    
  • .capture
    在 JS 中, addEventListener 事件傳遞預設是 Bubbling,如果要變成 Capturing ,就需要將第三個參數改成 true
    在 Vue 裡,如果想把觸發時機點改成 Capturing ,可以直接使用修飾符 .capture

    <div class="changeTarget" v-on:click.capture="changeTarget('div')">
      <button type="button" v-on:click.stop="changeTarget('button')">changeTarget</button>
    </div>
    
  • .self
    在 Vue 文件說明裡,可以知道當元素事件監聽加入修飾符 .self 後,只有當這個元素是 AT_TARGET 階段(透過 event.eventPhase 查詢,值為2)才能觸發該元素的事件。

    <!-- only trigger handler if event.target is the element itself -->
    <div class="changeTarget" v-on:click.self="changeTarget('div')">
      <span class="changeTarget" v-on:click="changeTarget('innerSpan')">
        <button type="button" v-on:click="changeTarget('button')">changeTarget</button>
      </span>
    </div>
    

    .capture.stop 比較

    <!-- only trigger handler if event.target is the element itself -->
    <div class="changeTarget" v-on:click.capture.self="changeTarget('div')">
      <span class="changeTarget" v-on:click.capture.stop="changeTarget('innerSpan')">
        <button type="button" v-on:click="changeTarget('button')">changeTarget</button>
      </span>
    </div>
    

    .capture.stop 是指元素在捕獲階段執行完事件並阻止後續元素的事件發生,但該元素的 event.eventPhase 值還是 1 ,但 .self 是指元素只有在 event.eventPhase 值是 2 的情況才能被執行,所以即使設定 <div class="changeTarget" v-on:click.capture.self="changeTarget('div')"></div> 在捕獲階段執行事件,但因為 <div>event.eventPhase 值是 1 ,所以事件不被執行。

  • .once
    使用修飾符 .once ,該事件只能被執行1次。

     <div class="changeTarget" v-on:click.once="changeTarget('div')">
      <span class="changeTarget" v-on:click.once="changeTarget('innerSpan')">
        <button type="button" v-on:click.once="changeTarget('button')">changeTarget</button>
      </span>
    </div>
    
  • .passive
    看了 MDN 對於參數 passive 的介紹,主要是針對 touch 某些事件在 scrolling 事件發生時,會有停頓延遲的情況,參數 passive 預設是 false ,當參數 passive 改為 true 時,可以改善scrolling 事件停頓延遲這個問題。

MDN-Improving scrolling performance with passive listeners

Improving Scroll Performance with Passive Event Listeners

加入按鍵修飾符的 v-on 指令

透過加入按鍵修飾符,以決定使用哪個按鍵來執行事件。
常見的幾個按鍵修飾符如下:

  • .enter
  • .tab
  • .delete (“删除”和“退格”鍵)
  • .esc
  • .space
  • .up
  • .down
  • .left
  • .right
  • .ctrl
  • .alt
  • .shift

單一按鍵修飾符

<input type="text" v-on:keyup.enter="addTodo" v-model="newTodo">

監聽鍵盤中 enter 按鍵的 keyup 事件,當 enter 按鍵被按下再鬆開後就會去執行所綁定的函式 addTodo

多個按鍵修飾符

<input type="text" v-on:keyup.alt.67="clear" v-model="newTodo">

監聽鍵盤中 alt 跟 C 按鍵的 keyup 事件,必須特別注意的是當 .alt.ctrlshift 等修飾鍵與其他按鍵或事件組合時,事件要觸發的話, .alt.ctrlshift 等修飾鍵是必須處於按下的狀態的,例如同時按下 alt 跟 C 按鍵,並不會觸發 clear 事件,按下 alt 跟 C 按鍵後僅放開 alt 按鍵,也不會觸發事件,只有在按下 alt 跟 C 按鍵後放開 C 按鍵( alt 按鍵仍須持續按著)才會觸發事件。

同理

<button type="button" v-on:click.ctrl="addTodo">addTodo</button>

如果要觸發事件必須是 ctrl 按鍵持續按著並點擊按鈕才能觸發事件。

加入滑鼠修飾符的 v-on 指令

加入滑鼠按鈕修飾符的狀況下,只有那個滑鼠按鈕才能觸發事件。

  • .left

  • .right

  • .middle

<button type="button" v-on:click.right="addTodo">addTodo</button>

Demo:[DAY08]跟 Vue.js 認識的30天 - Vue 的事件監聽

參考資料:

Vue.js-事件处理

Yes


上一篇
[DAY07]跟 Vue.js 認識的30天 - Vue 的列表渲染
下一篇
[DAY09]跟 Vue.js 認識的30天 - Vue 的資料雙向綁定
系列文
跟 VueJS 認識的30天21
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言