vue中的事件修飾符.self、.capture和.passive

vue中的事件修飾符有6種:

  • .stop
  • .prevent
  • .capture
  • .once
  • .self
  • .passive

.stop是stopPropagation停止冒泡,
.prevent是preventDefault阻止默認事件,
.once是點擊事件將只會觸發一次

<!-- 點擊事件將只會觸發一次 -->
<a v-on:click.once="doThis"></a>

1、.self

只在目標Dom是綁定了動作的Dom才觸發
也就是說只有這個Dom綁定了這個事件,且觸發的dom是這個目標dom,纔會觸發這個事件。**

實例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>.self修飾符</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <div id='app'>
        <div @click="log('11')" @click.self="log('12')" style="background-color: aqua; height: 400px; width: 400px;">
            <div @click="log('21')" @click.self="log('22')" style="background-color: #2195de; height: 200px; width: 400px;">
                <div @click.prevent="log('31')" @click.self="log('32')" style="background-color: #9521de; height: 100px; width: 400px;color:#fff;line-height: 100px;text-align: center;">事件修飾符探索</div>
            </div>
        </div>
    </div>
    <script>
        var app = new Vue({
            el:"#app",
            methods:{
                log(value){
                    console.log(value)
                }
            }
        })
    </script>
</body>
</html>

可以看到有三塊區域:1是最外層,2是第二層,3是最裏層。
1包栝2和3,2包括3
在這裏插入圖片描述
那麼我點擊區域3,打印出:
在這裏插入圖片描述
先觸發的是區域3中的.prevent和.self修飾符事件,然後是區域2中的點擊事件,但是.self事件沒有觸發,最後是區域1中的點擊事件,同樣.self事件沒有觸發。因爲我們的目標DOM是區域3,所以觸發的是區域3中的.self。
我們注意到區域2和區域3都是在事件冒泡階段觸發的,這個一定要注意,因爲跟下面要講解的.capture有關。
如果.prevent改爲.stop,那麼區域2和3的點擊事件是不會觸發的。

那麼我們點擊觸發區域2呢?
在這裏插入圖片描述
可以看到打印出的情況,這時區域2中的.self修飾符事件也觸發了。因爲我們的目標對象是區域2。

2、.capture

capture漢語意思:捕獲
主要是在事件的捕獲階段觸發父級元素的事件。
剛纔在上面的.self的例子中我們說了目標元素的外層元素的事件是在事件冒泡階段觸發的。那如果加上.capture修飾符,就會在事件的捕獲階段觸發。

實例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>.self修飾符</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <div id='app'>
        <div @click.capture="log('11')" @click="log('12')" @click.self="log('13')" style="background-color: aqua; height: 400px; width: 400px;">
            <div @click.capture="log('21')" @click="log('22')" @click.self="log('23')" style="background-color: #2195de; height: 200px; width: 400px;">
                <div @click.stop="log('31')" @click.self="log('32')" style="background-color: #9521de; height: 100px; width: 400px;color:#fff;line-height: 100px;text-align: center;">事件修飾符探索</div>
            </div>
        </div>
    </div>
    <script>
        var app = new Vue({
            el:"#app",
            methods:{
                log(value){
                    console.log(value)
                }
            }
        })
    </script>
</body>
</html>

在這裏插入圖片描述
我們點擊區域3,可以看到
在這裏插入圖片描述
這裏發現先觸發了區域1和2中的事件,然後再到區域3中的事件。
說明加上.capture修飾符是在捕獲階段觸發了事件。
因爲設置了stop所以冒泡階段的事件沒有觸發,沒有打印出22,12,如果不加stop,會打印出22,12的

使用修飾符時,順序很重要;相應的代碼會以同樣的順序產生。因此,用 v-on:click.prevent.self 會阻止所有的點擊,而 v-on:click.self.prevent 只會阻止對元素自身的點擊。

3、.passive

漢語意思:被動的,消極的;被動語態的
.passive 會告訴瀏覽器你不想阻止事件的默認行爲
prevent 是攔截默認事件,passive是不攔截默認事件。
passive這個修飾符會執行默認方法。你們可能會問,明明默認執行爲什麼會設置這樣一個修飾符。這就要說一下這個修飾符的本意了。

某些標籤擁有自身的默認事件,如a[href="#"],button[type=“submit”] 這種標籤在冒泡結束後會開始執行默認事件。注意默認事件雖然是冒泡後開始,但不會因爲stop阻止事件傳遞而停止。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>.self修飾符</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <div id='app'>
        <div @click.capture="log('11')" @click="log('12')" @click.self="log('13')" style="background-color: aqua; height: 400px; width: 400px;">
            <div @click.capture="log('21')" @click="log('22')" @click.self="log('23')" style="background-color: #2195de; height: 200px; width: 400px;">
                <div @click.capture.stop="log('31')" @click.self="log('32')" style="background-color: #9521de; height: 100px; width: 400px;color:#fff;line-height: 50px;text-align: center;">
                    <a @click="log('41')" href="javascript: console.log('默認事件')" style="display: block;height: 50px;width: 4oopx;background-color: red;">點擊a標籤</a>
                </div>
            </div>
        </div>
    </div>
    <script>
        var app = new Vue({
            el:"#app",
            methods:{
                log(value){
                    console.log(value)
                }
            }
        })
    </script>
</body>
</html>

在這裏插入圖片描述
點擊a標籤,打印的數據如下:
在這裏插入圖片描述
因爲在代碼中寫了@click.capture.stop="log(‘31’)"這一行,所以第三次捕獲後終止事件傳遞,沒有打印41,但不會阻止默認事件。

上面的代碼進行了一些改動,如下:

<div id='app'>
        <div @click.capture="log('11')" @click="log('12')" @click.self="log('13')" style="background-color: aqua; height: 400px; width: 400px;">
            <div @click.capture="log('21')" @click="log('22')" @click.self="log('23')" style="background-color: #2195de; height: 200px; width: 400px;">
                <div @click.capture="log('31')" @click="log('32')" @click.self="log('33')" style="background-color: #9521de; height: 100px; width: 400px;color:#fff;line-height: 50px;text-align: center;">
                    <a @click="log('41')" @click.capture="log('42')" href="javascript: console.log('默認事件')" style="display: block;height: 50px;width: 4oopx;background-color: red;">點擊a標籤</a>
                </div>
            </div>
        </div>
    </div>

打印結果如下:
在這裏插入圖片描述
注意一點:默認事件在冒泡事件之後執行

使用.passive修飾符的原因:

瀏覽器只有等內核線程執行到事件監聽器對應的JavaScript代碼時,才能知道內部是否會調用preventDefault函數來阻止事件的默認行爲,所以瀏覽器本身是沒有辦法對這種場景進行優化的。這種場景下,用戶的手勢事件無法快速產生,會導致頁面無法快速執行滑動邏輯,從而讓用戶感覺到頁面卡頓

通俗點說就是每次事件產生,瀏覽器都會去查詢一下是否有preventDefault阻止該次事件的默認動作。我們加上passive就是爲了告訴瀏覽器,不用查詢了,我們沒用preventDefault阻止默認動作。

這裏一般用在滾動監聽,@scoll,@touchmove 。因爲滾動監聽過程中,移動每個像素都會產生一次事件,每次都使用內核線程查詢prevent會使滑動卡頓。我們通過passive將內核線程查詢跳過,可以大大提升滑動的流暢度。

注:passive和prevent衝突,不能同時綁定在一個監聽器上。

參考文章:Vue事件修飾符(二).prevent .passive

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章