• 03-v-on的事件修饰符

    # v-on的事件修饰符

    # v-on的常见事件修饰符

    v-on 提供了很多事件修饰符来辅助实现一些功能。事件修饰符有如下:

    • .stop 阻止冒泡。本质是调用 event.stopPropagation()。

    • .prevent 阻止默认事件(默认行为)。本质是调用 event.preventDefault()。

    • .capture 添加事件监听器时,使用捕获的方式(也就是说,事件采用捕获的方式,而不是采用冒泡的方式)。

    • .self 只有当事件在该元素本身(比如不是子元素)触发时,才会触发回调。

    • .once 事件只触发一次。

    • .{keyCode | keyAlias} 只当事件是从侦听器绑定的元素本身触发时,才触发回调。

    • .native 监听组件根元素的原生事件。

    PS:一个事件,允许同时使用多个事件修饰符。

    写法示范:

              <!-- click事件 -->
            <button v-on:click="doThis"></button>
    
            <!-- 缩写 -->
            <button @click="doThis"></button>
    
            <!-- 内联语句 -->
            <button v-on:click="doThat('hello', $event)"></button>
    
            <!-- 阻止冒泡 -->
            <button @click.stop="doThis"></button>
    
            <!-- 阻止默认行为 -->
            <button @click.prevent="doThis"></button>
    
            <!-- 阻止默认行为,没有表达式 -->
            <form @submit.prevent></form>
    
            <!--  串联修饰符 -->
            <button @click.stop.prevent="doThis"></button>
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20

    # .stop的举例

    我们来看下面这个例子:

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
        <script src="vue2.5.16.js"></script>
        <style>
            .father {
                height: 300px;
                width: 300px;
                background: pink;
            }
    
            .child {
                width: 200px;
                height: 200px;
                background: green;
            }
        </style>
    </head>
    
    <body>
        <div id="app">
            <div class="father" @click="fatherClick">
                <div class="child" @click="childClick">
                </div>
            </div>
        </div>
        <script>
    
            var vm = new Vue({
                el: '#app',
                data: {},
                methods: {
                    fatherClick: function () {
                        console.log('father 被点击了');
                    },
                    childClick: function () {
                        console.log('child 被点击了');
                    }
                }
            })
    
        </script>
    </body>
    
    </html>
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51

    上方代码中,存在冒泡的现象,父标签中包含了一个子标签。当点击子标签时,父标签也会被触发。打印顺序是:

      child 被点击了
      father 被点击了
    
    1
    2

    那么问题来了,如果我不想让子标签的点击事件冒泡到父亲,该怎么做呢?办法是:给子标签加一个事件修饰符.stop,阻止冒泡。代码如下:

        <div class="child" @click.stop="childClick">
    
    1

    阻止冒泡后,当点击子标签时,打印结果是:

      child 被点击了
    
    1

    PS:我发现一个有意思的现象。上方的这行代码中,如果把.stop改为:stop,造成的现象是,父标签被触发了,而子标签没有被触发。

    # .capture举例

    .capture:触发事件时,采用捕获的形式,而不是冒泡的形式。

    还是采用上面的例子:当按钮点击时,如果想要采取捕获的方式,而不是冒泡的方式,办法是:可以直接在父标签上加事件修饰符.capture。代码如下:

        <div class="father" @click.capture="fatherClick">
    
    1

    当点击子标签时,打印结果是:

      father 被点击了
      child 被点击了
    
    1
    2

    # .prevent的举例1

    比如说,超链接<a>默认有跳转行为,那我可以通过事件修饰符.prevent阻止这种跳转行为。

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
        <script src="vue2.5.16.js"></script>
    </head>
    
    <body>
        <div id="app">
            <!-- 通过 .prevent 阻止超链接的默认跳转行为 -->
            <a href="http://www.baidu.com" @click.prevent="linkClick">百度一下</a>
        </div>
        <script>
    
            var vm = new Vue({
                el: '#app',
                data: {},
                methods: {
                    linkClick: function () {
                        console.log('超链接被点击了');
                    }
                }
            })
        </script>
    </body>
    
    </html>
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31

    上方代码中:

    • 如果去掉.prevent,点击按钮后,既会打印log,又会跳转到百度页面。

    • 现在加上了.prevent,就只会打印log,不会跳转到百度页面。

    # .prevent的举例2

    现在有一个form表单:

        <form action="http://www.baidu.com">
          <input type="submit" value="表单提交">
        </form>
    
    1
    2
    3

    我们知道,上面这个表单因为type="submit",因此它是一个提交按钮,点击按钮后,这个表单就会被提交到form标签的action属性中指定的那个页面中去。这是表单的默认行为。

    现在,我们可以用.prevent来阻止这种默认行为。修改为:点击按钮后,不提交到服务器,而是执行我们自己想要的事件(在submit方法中另行定义)。如下:

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <title>Document</title>
      <script src="vue2.5.16.js"></script>
    </head>
    
    <body>
      <div id="app">
        <!-- 阻止表单中submit的默认事件 -->
        <form @submit.prevent action="http://www.baidu.com">
          <!-- 执行自定义的click事件 -->
          <input type="submit" @click="mySubmit" value="表单提交">
        </form>
    
      </div>
    </body>
    
    <script>
      new Vue({
        el: '#app',
        data: {
        },
        methods: {
          mySubmit: function() {
            alert('ok');
          }
        }
      });
    </script>
    
    </html>
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34

    上方代码中,我们通过.prevent阻止了提交按钮的默认事件,点击按钮后,执行的是mySubmit()方法里的内容。这个方法名是可以随便起的,我们甚至可以起名为submit,反正默认的submit已经失效了。

    # .self举例

    • .self 只有当事件在该元素本身(比如不是子元素)触发时,才会触发回调。

    我们知道,在事件触发机制中,当点击子标签时,父标签会通过冒泡的形式被触发(父标签本身并没有被点击)。可如果我给父标签的点击事件设置.self修饰符,达到的效果是:子标签的点击事件不会再冒泡到父标签了,只有点击符标签本身,父标签的事件才会被触发。代码如下:

        <div class="father" @click.self="fatherClick">
    
    1

    疑问:既然.stop.self都可以阻止冒泡,那二者有什么区别呢?区别在于:前者能够阻止整个冒泡行为,而后者只能阻止自己身上的冒泡行为。