1. 程式人生 > >Vue.js例項學習:事件處理

Vue.js例項學習:事件處理

一、監聽事件

可以用 v-on 指令監聽 DOM 事件,並在觸發時執行一些 JavaScript 程式碼。( v-on: 簡寫為@)

<div id="app">
  <button @click = "count++">加 1</button>
  <button @click = "count--">減 1</button>
  <p>{{count}}</p>
</div>
<script type="text/javascript">
var vm = new Vue({
  el:'#app'
, data:{ count:0 } });
</script>

輸出:初始值為0
這裡寫圖片描述
點選”加1”就增加1,同理點選”減1”就減少1
這裡寫圖片描述

二、事件處理方法

許多事件處理邏輯會很複雜,所以直接把 JavaScript 程式碼寫在 v-on 指令中是不可行的。因此 v-on 還可以接收一個需要呼叫的方法名稱。

1、呼叫無引數方法

順便補一下js的event:
1) 將even(事件)作為引數,就是這個“點選”事件,通過這個even,可以獲取到event.target,就是點選的物件等等屬性。PS:那個even引數可加可不加,需要用到的時候就加。
2) event也就是事件的意思,就相當於把這個事件的物件傳給這個方法,event包含了這個事件的所有引數和資訊

<div id="app">
  <button @click = "greet">button</button>
</div>
<script type="text/javascript">
var vm = new Vue({
  el:'#app',
  data:{
    name:"bty"
  },
  methods:{
    greet:function(event){//因為上面沒有給該函式傳遞引數,所以給他個引數時,系統預設為event,可以隨便起名字(阿毛,阿狗) 

      console.log("out"
); //`event` 是原生 DOM 事件,與上面的event(阿毛,阿狗)對應上即可,意思是,如果是一個 事件 就輸出觸發事件標籤的標籤名; //this在方法裡指當前 Vue 例項 if(event && this.name != ""){ // 會輸出標籤的名稱 BUTTON,這一行的event是固定寫法,必須通過event物件呼叫 console.log(event.target.tagName); } } } });
</script>

控制檯輸出:
out
BUTTON

2、有引數方法:內聯處理器中的方法

除了直接繫結到一個方法,也可以在內聯 JavaScript 語句中呼叫方法:
(1)

<div id="app">
  <button @click = "say('bty')">say bty</button>
  <button @click = "say('bty2')">say bty2</button>
</div>
<script type="text/javascript">
var vm = new Vue({
  el:'#app',
  data:{
    name:"bty"
  },
  methods:{
    say:function(message){
      console.log(message);
    }
  }
});
</script>

這裡寫圖片描述
點選”say bty” , 控制檯輸出:bty
點選”say bty2” , 控制檯輸出:bty2

(2) $ event

有時也需要在內聯語句處理器中訪問原始的 DOM 事件。可以用特殊變數 $event 把它傳入方法:

<div id="app">
  <input type="submit" @click = "warn('Form cannot be submitted yet.', $event)">
</div>
<script type="text/javascript">
var vm = new Vue({
  el:'#app',
  data:{
    name:"bty"
  },
  methods:{
    warn:function(message,event){    
      if(event){
        console.log("do if");
        event.preventDefault();
      }
      console.log(message);
    }
  }
});
</script>

點選提交按鍵,控制檯輸出:
do if
Form cannot be submitted yet.


問:“第一個無引數 和 內聯處理器中的方法 有什麼區別?“
答:“請觀察,一個有括號,一個沒括號,對吧?
沒括號的這個,直接就是函式名,有括號的這個,實際是一條JS語句,有括號的這個就叫『內聯處理器』。“具體詳解見該連結

三、修飾符

1、事件修飾符

在事件處理中呼叫 event.preventDefault() 或 event.stopPropagation() 是非常常見的需求。儘管實現很輕鬆,但更好的方式是:方法只有純粹的資料邏輯,而不是去處理 DOM 事件細節。

為了解決這個問題,Vue.js 為 v-on 提供了 事件修飾符。之前提過,修飾符是由點開頭的指令字尾來表示的。

  • .stop
  • .prevent
  • .capture
  • .self
  • .once
<!-- 阻止單擊事件繼續傳播 -->
<a v-on:click.stop="doThis"></a>

<!-- 提交事件不再過載頁面 -->
<form v-on:submit.prevent="onSubmit"></form>

<!-- 修飾符可以串聯 -->
<a v-on:click.stop.prevent="doThat"></a>

<!-- 只有修飾符 -->
<form v-on:submit.prevent></form>

<!-- 新增事件監聽器時使用事件捕獲模式 -->
<!-- 即元素自身觸發的事件先在此處處理,然後才交由內部元素進行處理 -->
<div v-on:click.capture="doThis">...</div>

<!-- 只當在 event.target 是當前元素自身時觸發處理函式 -->
<!-- 即事件不是從內部元素觸發的 -->
<div v-on:click.self="doThat">...</div>

<!-- 滾動事件的預設行為 (即滾動行為) 將會立即觸發 -->
<!-- 而不會等待 `onScroll` 完成  -->
<!-- 這其中包含 `event.preventDefault()` 的情況 -->
<div v-on:scroll.passive="onScroll">...</div>

注:
1⃣️使用修飾符時,順序很重要;相應的程式碼會以同樣的順序產生。

  • v-on:click.prevent.self 會阻止所有的點選
  • v-on:click.self.prevent 只會阻止對元素自身的點選。

2⃣️不要把 .passive 和 .prevent 一起使用,因為 .prevent 將會被忽略,同時瀏覽器可能會向你展示一個警告。請記住,.passive 會告訴瀏覽器你不想阻止事件的預設行為。

2、按鍵修飾符

在監聽鍵盤事件時,我們經常需要檢查常見的鍵值。Vue 允許為 v-on 在監聽鍵盤事件時新增按鍵修飾符:

<!-- 只有在 `keyCode` 是 13 時呼叫 `vm.submit()` -->
<input v-on:keyup.13="submit">

(1)按鍵修飾符別名

記住所有的 keyCode 比較困難,所以 Vue 為最常用的按鍵提供了別名:

<!-- 同上 -->
<input v-on:keyup.enter="submit">

<!-- 縮寫語法 -->
<input @keyup.enter="submit">

全部的按鍵別名:

  • .enter
  • .tab
  • .delete (捕獲“刪除”和“退格”鍵)
  • .esc
  • .space
  • .up
  • .down
  • .left
  • .right

(2)自定義按鍵修飾符別名
我們可以通過全域性 config.keyCodes 物件自定義按鍵修飾符別名:

<!-- 可以使用 `v-on:keyup.f1` -->
Vue.config.keyCodes.f1 = 112

(3)自動匹配按鍵修飾符
你也可直接將 KeyboardEvent.key 暴露的任意有效按鍵名轉換為 kebab-case 來作為修飾符:

<!-- 處理函式僅在 $event.key === 'PageDown' 時被呼叫 -->
<input @keyup.page-down="onPageDown">

注:有一些按鍵 (.esc 以及所有的方向鍵) 在 IE9 中有不同的 key 值, 如果你想支援 IE9,它們的內建別名應該是首選。

3、系統修飾鍵

(1)普通的:
可以用如下修飾符來實現僅在按下相應按鍵時才觸發滑鼠或鍵盤事件的監聽器。

  • .ctrl
  • .alt
  • .shift
  • .meta

注意:在 Mac 系統鍵盤上,meta 對應 command 鍵 (⌘)。在 Windows 系統鍵盤 meta 對應 Windows 徽標鍵 (⊞)。在 Sun 作業系統鍵盤上,meta 對應實心寶石鍵 (◆)。在其他特定鍵盤上,尤其在 MIT 和 Lisp 機器的鍵盤、以及其後繼產品,比如 Knight 鍵盤、space-cadet 鍵盤,meta 被標記為“META”。在 Symbolics 鍵盤上,meta 被標記為“META”或者“Meta”。

例如:

<!-- Alt + C -->
<input @keyup.alt.67="clear">

<!-- Ctrl + Click -->
<div @click.ctrl="doSomething">Do something</div>

這裡寫圖片描述

(2)更精準的:
.exact 修飾符允許你控制由精確的系統修飾符組合觸發的事件。

<!-- 即使 Alt 或 Shift 被一同按下時也會觸發 -->
<button @click.ctrl="onClick">A</button>

<!-- 有且只有 Ctrl 被按下的時候才觸發 -->
<button @click.ctrl.exact="onCtrlClick">A</button>

<!-- 沒有任何系統修飾符被按下的時候才觸發 -->
<button @click.exact="onClick">A</button>

(3)滑鼠按鈕修飾符

  • .left
  • .right
  • .middle

這些修飾符會限制處理函式僅響應特定的滑鼠按鈕。


為什麼在 HTML 中監聽事件?

你可能注意到這種事件監聽的方式違背了關注點分離 (1、何為關注點分離2、關注點分離應用例項) 這個長期以來的優良傳統。但不必擔心,因為所有的 Vue.js 事件處理方法和表示式都嚴格繫結在當前檢視的 ViewModel 上,它不會導致任何維護上的困難。實際上,使用 v-on 有幾個好處:

  • 掃一眼 HTML 模板便能輕鬆定位在 JavaScript 程式碼裡對應的方法。
  • 因為你無須在 JavaScript 裡手動繫結事件,你的 ViewModel 程式碼可以是非常純粹的邏輯,和 DOM 完全解耦,更易於測試。
  • 當一個 ViewModel 被銷燬時,所有的事件處理器都會自動被刪除。你無須擔心如何自己清理它們。