iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 5
0
自我挑戰組

網頁前端框架 Vue 3 從頭開始系列 第 5

vue.js 3.x 學習手冊 (5) 事件 修飾符

上一篇文章提到了Vue結合了事件上的用法,這篇文章來加強一下事件上的使用:

事件修飾符

事件修飾符在vue裡面也是極為好用,透過下面這個範例來說明:

HTML
<div id="app">
    <div class="header">
        <div class="nav">
            <form>
                <input type="submit" @click="submitFn" value="Submit">
                <input type="button" @click="clearFn" value="Clear">
            </form>
        </div>
    </div>
    <div v-html="action"></div>
</div>
Javascript
const app = Vue.createApp({
    data() {
        return {
            action: '',
        }
    },
    methods: {
        submitFn() {
            this.action += "表單送出<br>";
        },
        clearFn() {
            this.action = '';
        }
    }
}).mount('#app');

修飾符使用前

可以看到範例中form有一個input按鈕,因為type設定成submit,所以每次按下的時候都會觸發表單送出的動作,所以你會看到上面的案例會閃爍一段字出來之後馬上消失,那是因為頁面已經重新整理了,另外文字的部分,這次我們是利用v-html綁定一個數據來呈現HTML格式的內容。

碰到這樣的情況,在Javascript會使用preventDefault來阻止觸發預設的事件,在vue裡面我們可以這麼做:

<input type="submit" @click.prevent="submitFn" value="Submit">

修飾符使用後

透過@click.prevent就可以達到preventDefault的功能,另外來看以下的狀況:

HTML
<div id="app">
    <div class="header">
        <div class="nav" @click="navFn">
            <form>
                <input type="submit" @click.prevent="submitFn" value="Submit">
                <input type="button" @click="clearFn" value="Clear">
            </form>
        </div>
    </div>
    <div v-html="action"></div>
</div>
Javascript
const app = Vue.createApp({
    data() {
        return {
            action: '',
        }
    },
    methods: {
        submitFn() {
            this.action += "表單送出<br>";
        },
        navFn() {
            this.action += "選單點選<br>";
        },
        clearFn() {
            this.action = '';
        }
    }
}).mount('#app');

Event Bubbles 修改前

這個範例與上面的案例差不多,差別是我在nav上面也監聽了Click事件,並且去執行navFn,大家應該已經看出了這邊想要說明什麼了吧?這個頁面上的按鈕在按下後雖然不會觸發表單送出的動作,但會把Click事件繼續往上傳,並且觸發navFn(),所以按鈕按下會同時觸發兩個Function。

為了阻止事件的上傳,我們會在Javascript中加入stopPropagation阻止事件的上傳,在vue裡面我們可以這麼做就好:

<input type="submit" @click.prevent.stop="submitFn" value="Submit">
<input type="button" @click.stop="clearFn" value="Clear">

Event Bubbles 修改後

可以看到我們把“事件修飾符”串接在一起,可以同時達到preventDefault和stopPropagation的效果。

另外大家可以透過上面的訊息看出來執行順序是submitFn先執行,再往上回傳執行navFn,也就是內層先執行在往上回傳事件後觸發外層的Function,這也是一般Javascript正確的事件執行與回傳機制,但我們只要把Code修正成這樣:

<div class="nav" @click.capture="navFn">
    <form>
        <input type="submit" @click.prevent="submitFn" value="Submit">
        <input type="button" @click="clearFn" value="Clear">
    </form>
</div>

透過@click.capture=”navFn”,就能夠做到先將本身觸發的函數先執行完畢後再下傳事件的效果。

範例檔

關於修飾符在這邊做個整理,就不再給出更多的範例了。

<!--
vue事件修飾符:
.stop
.prevent
.capture
.self
.once
.passive
-->
<!-- 阻止事件的傳遞 -->
<a @click.stop="doSomething">...</a>
<!-- 觸發Submit事件時不重新整理頁面 -->
<form @submit.prevent="doSomething">...</form>
<!-- 處理完畢後再將事件往下傳 -->
<div @click.capture="doSomething">...</div>
<!-- 只在被點擊對象是自己的時候執行 -->
<div @click.self="doSomething">...</div>
<!-- 僅第一次按下時觸發動作 -->
<a @click.once="doSomething">...</div>
<!-- 捲動預設行為將立刻被觸發,不會等待doSomething完成,藉以提升行動裝置的效能 -->
<div @scroll.passive="doSomething">...</div>

按鍵修飾符

vue在監聽鍵盤事件上也非常方便,可以參考下面的範例:

<div id="app">
    <div class="header">
        <div class="nav">
            <form @keydown.prevent>
                <input type="text" @keydown.ctrl.enter="enterFn">
                <button @click.prevent.alt.exact="clickFn">檢查</button>
            </form>
        </div>
    </div>
    <div v-html="action"></div>
</div>

@keydown.prevent:會擋住在表單範圍內按下Enter鍵之後,自動送出表單的功能
@keydown.ctrl.enter=”enterFn”:使用者在此input中按下Ctrl + Enter時會觸發enterFn
@click.prevent.alt.exact=”clickFn”:使用者在需要按下鍵盤上的Alt + 滑鼠左鍵點擊按鈕才會觸發ClickFn,若將其中exact的部分拿掉,則按下鍵盤Alt + Shift + 左鍵,也會觸發該函數。

範例檔

除了使用名稱來表示鍵盤修飾符之外,也可以透過keycode來替代,例如:@keydown.13=”enterFn”,表示按下Enter鍵,除此之外在此列出一些常用的按鍵名稱:
enter
tab
delete
esc
space
up
down
left
right
ctrl
alt
shift
meta:Mac的Command鍵、Windows的Windows鍵
left:滑鼠左鍵
right:滑鼠右鍵
middle:滑鼠中鍵
以上就是vue針對事件方面的一些操作,希望對大家有幫助!


上一篇
vue.js 3.x 學習手冊 (4) 事件
下一篇
vue.js 3.x 學習手冊 (6) 雙向資料綁定
系列文
網頁前端框架 Vue 3 從頭開始10
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言