跳至主要内容

[Vue] Vue指令-事件觸發

相關連結


v-on

我們使用v-on指令來指定觸發我們在methods內所撰寫的函式,基本使用方法為v-on:click="functionName"

如果不需帶入參數,則可以不用加入小括號,一樣可以執行。有加入參數的需求再加上小括號即可。

縮寫

因為v-on的使用頻率很高,所以vue有提供縮寫的形式。

e.g:v-on:click="functionName"可以縮寫為@click="functionName"

<div id="app">
<div class="p-5">
<h3>觸發事件 與 縮寫*</h3>
<div class="box" :class="{ rotate: isTransform }"></div>
<button class="btn btn-outline-primary" v-on:click="changeClass">選轉物件</button>
<br>
<h3>帶入參數*</h3>
<div class="box" :class="{ rotate: isTransform }"></div>
<button class="btn btn-outline-primary" @click="change('isTransform')">選轉物件</button>

<h3>原生 DOM 事件*</h3>
<!-- https://developer.mozilla.org/en-US/docs/Web/Events -->
<h4>input change 事件</h4>
<input type="text" @change="onChange">
<br><br>
<h4>form submit 事件</h4>
<form @submit.prevent="submitForm">
<input type="text" v-model="name">
<button>送出表單</button>
</form>

<h3>動態事件 []</h3>
<input type="text" @[event]="dynamicEvent">
<input type="text" v-model="event">

<h3>動態物件方法 {}</h3>
<!-- 此方法無法傳入參數 -->
<button class="box" v-on="{
mousedown:down,
mouseup:up
}">
</button>
</div>
</div>

基礎語法

v-on可以帶入DOM事件(W3C 參考資料)

如不需帶入參數,以click事件為範例:v-on:click="functionName",可縮寫為@click="functionName"

如需帶入參數:@click="functionName(params)

form上的submit事件

Line:17 ,我們可以在fomr上面綁定一個@submit事件,並且指定當事件觸發時要執行的函式。

如此一來,我們就不用受限於只能點選<button type="submit">送出按鈕</button> 才能將表單送出。

這邊使用prevent修飾符,來取消掉送出表單時預設的跳轉行為

動態綁定事件語法

與動態綁定class類似,如 Line:23 (對應vue data內的event變數),我們可以透過綁定v-model的input去動態修改event變數的內容,來決定我們要透過哪種方式觸發事件。

語法為@[儲存事件方法的變數]="functionName"

雖然實戰上比較少使用到動態綁定事件...

在同DOM上綁定多個事件

<div @="{
事件名稱一:觸發執行函式一,
事件名稱二:觸發執行函式二
}"></div>
綁定多事件時函式不可傳入參數

需要注意,當我們使用@="{}"去綁定多個事件的時候,我們的事件觸發函式不能傳入參數

否則函式會在一運行就直接觸發,不會等到事件條件滿足的時候才執行。

並且後續該事件也無法重複觸發。

v-on 修飾符

事件處理的修飾符很多,以下介紹幾種常用的修飾符。主要分為鍵盤以及滑鼠事件,另外還有針對事件本身的修飾符。

按鍵修飾符

建議閱讀官方文件

這部分有比較多規則,建議閱讀官方文件

別名修飾符

官方資料:按鍵別名

別名修飾包含:.enter, .tab, .delete, .esc, .space, .up, .down, .left, .right

使用方法如下:@keyup.enter="functionName"

系統按鍵修飾符

官方資料:系統按鍵修飾符

系統按鍵修飾符包含:.ctrl, .alt, .shift, .meta

系統按鍵修飾符與keyup的關係

@keyup.ctrl.enter="functionName"為例,只會在維持按下ctrl並且放開enter的時候才會觸發。

特定按鍵

顧名思義直接指定會觸發事件的案件,如 @keyup.a="functionName",可以指定在放開a按鈕的時候觸發事件。

複數特定案件

如果使用 @keyup.a.b="functionName",則點選a b都會觸發事件。而不是同時按下ab時才會觸發。

滑鼠修飾符

滑鼠按鍵修飾符

滑鼠按鍵修飾可以指定在點選哪個滑鼠按鍵的時候觸發,包含以下三種:

  • .left :點選滑鼠左鍵觸發
  • .right :點選滑鼠右鍵觸發
  • .middle :點選滑鼠中鍵觸發

事件修飾符

事件修飾符

事件修飾符包含以下幾種:.stop , .prevent , .self , .capture , .once , .passive

.prevent

最常使用的就是.prevent,只要需要取消DOM元素預設的事件行為(如表單跳轉,a連結跳轉等等)都會使用到這個修飾符。

冒泡事件簡介

Bubbling and capturing | JS.INFO

如果有巢狀的元素,並且每個元素上都有綁定事件時,預設是會向外尋找並且依序觸發的

<a href="https://javascript.info/bubbling-and-capturing">冒泡事件參考文章</a>
<div class="p-3 bg-success" @click="trigger('div')">
<span class="box d-flex align-items-center justify-content-center" @click="trigger('box')">
<button class="btn btn-outline-secondary" @click="trigger('button')">按我</button>
</span>
</div>

點選「按我」的按鈕時,也會依序向外觸發綁定在span上以及div上的事件。這時候就可以使用冒泡事件相關的事件修飾符號去防止冒泡事件的發生。

.stop

.stop修飾符可以防止向外再尋找冒泡事件。但是綁定修飾符本身的事件仍然會冒泡觸發

<h6 class="mt-3">stopPropagation (防止向外尋找)</h6>
<div class="p-3 bg-success" @click="trigger('div')">
<!-- 事件停止在span,不會向外再向div尋找 -->
<span class="box d-flex align-items-center justify-content-center" @click.stop="trigger('box')">
<button class="btn btn-outline-secondary" @click="trigger('button')">按我</button>
</span>
</div>

.capture

原本事件觸發順序為 button >> span >> div

使用.capture修飾符之後,觸發順序會由外往內依序觸發:div >> span >> button

所有綁定的事件都需要加上capture修飾符!!!

<h6 class="mt-3">事件偵聽器時使用 capture 模式 (事件改為由外而內)</h6>
<div class="p-3 bg-success" @click.capture="trigger('div')">
<span class="box d-flex align-items-center justify-content-center" @click.capture="trigger('box')">
<button class="btn btn-outline-secondary" @click.capture="trigger('button')">按我</button>
</span>
</div>

.self

.self修飾符會防止所有的冒泡事件,只觸發該事件本身範圍內。

同樣需要在所有的事件上加上.self修飾符!!!

<h6 class="mt-3">事件偵聽器時使用 self 模式 (只會觸發自己範圍內的)</h6>
<div class="p-3 bg-success" @click.self="trigger('div')">
<span class="box d-flex align-items-center justify-content-center" @click.self="trigger('box')">
<button class="btn btn-outline-secondary" @click.self="trigger('button')">按我</button>
</span>
</div>

.once

.once可以讓該事件只觸發一次。

需要注意使用.once仍然會有冒泡現象產生

<h3 class="mt-3">事件偵聽器只觸發一次 once</h3>
<div class="p-3 bg-success" @click.once="trigger('div')">
<span class="box d-flex align-items-center justify-content-center" @click.once="trigger('box')">
<button class="btn btn-outline-secondary" @click.once="trigger('button')">按我</button>
</span>
</div>

單次觸發的事件監聽

可以看到該事件上具有once:true

原生事件物件

HTML DOM Event Objects | w3schools

tabindex問題

codepen 中, Line:9 有一個按鍵事件,需要使用tabindex去focus並且使用enter觸發

但是safari無法正確選取到該元素,換成chrome就沒有問題了。

沒有帶入參數時

沒有帶入參數時,預設我們第一個參數就會是事件物件(event object):

<div id="app">
<div class="p-5">
<div class="box mt-5" :class="{ rotate: isTransform }"></div>
<hr>
<!-- 當沒有參數時,預設第一個則是 dom 事件參數 -->
<button class="btn btn-outline-primary" @click="changeClass">選轉物件</button>
<button class="btn btn-outline-primary" @keyup.enter="changeClass">按鈕事件</button>
</div>
</div>

帶入參數時

當我們一定要帶入參數到方法中時,我們可以在v-on所調用的方法中傳入$event變數,則所對應位置的參數內容就會帶入事件物件。

<div id="app">
<div class="p-5">
<!-- 當如果有參數時,則可以使用 $event -->
<button class="btn btn-outline-primary" @click="changeClassWithEvent('這段是自訂參數', $event)">自訂參數</button>
</div>
</div>