Vue的事件处理(监听、内联、修饰符、键码、鼠标、系统修饰符)


前言

在平常开发中,对 DOM 的操作很常见,然而 Vue 中是虚拟 DOM 不太提倡直接进行原生 DOM 操作,降低性能。在 Vue 中可以使用 v-on 指令来操作 DOM 事件。

知识点

  • 事件绑定指令
  • 事件处理方法
  • 内联方法
  • 修饰符

事件监听

我们来看个事件监听的简单示例—计数器。

<!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>syl-vue-test</title>
    <!-- 引入 vue.js -->
    <script src="vue.min.js"></script>
    <style>
      button {
        width: 150px;
        height: 40px;
        border-radius: 10px;
        background: green;
        outline: none;
        color: #fff;
      }
    </style>
  </head>
  <body>
    <div id="app">
      <!-- v-on:click 绑定点击监听 点一次 counter 累加一次-->
      <button v-on:click="counter+=1">点击</button>
      <p>你点了{{counter}}次</p>
    </div>
    <script>
      var app = new Vue({
        el: "#app",
        data: {
          counter: 0,
        },
      });
    </script>
  </body>
</html>

事件监听处理方法

许多事件处理逻辑会更为复杂,所以直接把 JavaScript 代码写在 v-on 指令中是不可行的。因此 v-on 还可以接收一个需要调用的方法名称。该方法写在 methods 对象中。

methods 对象中实现方法

<!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>syl-vue-test</title>
    <!-- 引入 vue.js -->
    <script src="vue.min.js"></script>
    <style>
      button {
        width: 150px;
        height: 40px;
        border-radius: 10px;
        background: green;
        outline: none;
        color: #fff;
      }
    </style>
  </head>
  <body>
    <div id="app">
      <!-- 绑定点击监听 -->
      <button v-on:click="say">点击</button>
    </div>
    <script>
      var app = new Vue({
        el: "#app",
        data: {
          counter: 0,
        },
        methods: {
          // 声明事件点击监听 say 方法
          say: function (event) {
            // 监听事件回调处理 event.type 触发事件类型 说明:`${}` 为 es6 模板字符串,拼接字符串的
            alert(`小楼提醒:你触发了${event.type}事件`);
          },
        },
      });
    </script>
  </body>
</html>

内联处理器的方法

不同元素触发同一事件或不同事件,调用同用一个方法。例子:

<!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>syl-vue-test</title>
    <!-- 引入 vue.js -->
    <script src="vue.min.js"></script>
    <style>
      button {
        width: 150px;
        height: 40px;
        border-radius: 10px;
        background: green;
        outline: none;
        color: #fff;
      }
    </style>
  </head>
  <body>
    <div id="app">
      <!-- 绑定点击监听 共用 say 方法-->
      <button v-on:click="say('实验楼')">实验楼</button>
      <button v-on:click="say('小楼')">小楼</button>
    </div>
    <script>
      var app = new Vue({
        el: "#app",
        data: {},
        methods: {
          // 声明事件点击监听 say 方法
          say: function (name) {
            alert(`我是${name}`);
          },
        },
      });
    </script>
  </body>
</html>

事件修饰符

在事件处理程序中调用 event.preventDefault() 或 event.stopPropagation() 是非常常见的需求,阻止事件冒泡或捕获或者事件默认行为。尽管我们可以在方法中轻松实现这点,但更好的方式是:方法只有纯粹的数据逻辑,而不是去处理 DOM 事件细节。

为了解决这个问题,Vue.js 为 v-on 提供了 事件修饰符。之前提过,修饰符是由点开头的指令后缀来表示的。

  • .stop:阻止单击事件继续传播。
  • .prevent:阻止事件默认行为。
  • .capture:添加事件监听器时使用事件捕获模式。
  • .self:只当在 event.target 是当前元素自身时触发处理函数。
  • .once:点击事件将只会触发一次。
  • .passive:滚动事件的默认行为 (即滚动行为) 将会立即触发。
  • .stop 修饰符的应用。

未添加 .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>syl-vue-test</title>
    <!-- 引入 vue.js -->
    <script src="vue.min.js"></script>
    <style>
      /* 居中 */
      .super,
      .child {
        position: absolute;
        top: 0;
        left: 0;
        bottom: 0;
        right: 0;
        margin: auto;
      }
      .super {
        width: 300px;
        height: 300px;
        background: pink;
      }
      .super .child {
        width: 100px;
        height: 100px;
        background: green;
      }
    </style>
  </head>
  <body>
    <div id="app">
      <div class="super" v-on:click="handleClick('super')"><div class="child" v-on:click="handleClick('child')"></div>
      </div>
    </div>
    <script>
      var app = new Vue({
        el: "#app",
        data: {},
        methods: {
          // 声明事件点击监听 handleClick
          handleClick: function (name) {
            alert(`我是${name}`);
          },
        },
      });
    </script>
  </body>
</html>

添加修饰符:

<div id="app">
  <div class="super" v-on:click.stop="handleClick('super')"><div class="child" v-on:click.stop="handleClick('child')"></div>
  </div>
</div>

按键修饰符

在监听键盘事件时,我们经常需要检查详细的按键。Vue 允许为 v-on 在监听键盘事件时添加按键修饰符:

  • .enter
<!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>syl-vue-test</title>
    <!-- 引入 vue.js -->
    <script src="vue.min.js"></script>
  </head>
  <body>
    <div id="app">
      <input
        type="text"
        v-on:keyup.enter="alert('你按了enter,确定输入完毕?')"
      />
    </div>
    <script>
      var app = new Vue({
        el: "#app",
      });
    </script>
  </body>
</html>
  • .tab
  • .delete (捕获“删除”和“退格”键)
  • .esc
  • .space
  • .up
  • .down
  • .left
  • .right

键码 keycode

使用 keyCode 特征,了解更多键码:
在这里插入图片描述

<!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>syl-vue-test</title>
    <!-- 引入 vue.js -->
    <script src="vue.min.js"></script>
  </head>
  <body>
    <div id="app">
      <!-- 文本框内按了键码为 13 的键(enter) 提示是否输入完毕 -->
      <input type="text" v-on:keyup.13="alert('你按了enter,确定输入完毕?')" />
    </div>
    <script>
      var app = new Vue({
        el: "#app",
      });
    </script>
  </body>
</html>

系统修饰符

系统特定的组合功能键,如 ctrl+c、ctrl+v。

可以用如下修饰符来实现仅在按下相应按键时才触发鼠标或键盘事件的监听器。

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

说明:在 Mac 系统键盘上,meta 对应 command 键 (⌘)。在 Windows 系统键盘 meta 对应 Windows 徽标键 (⊞)。在 Sun 操作系统键盘上,meta 对应实心宝石键 (◆)。在其他特定键盘上,尤其在 MIT 和 Lisp 机器的键盘、以及其后继产品,比如 Knight 键盘、space-cadet 键盘,meta 被标记为 “META”。在 Symbolics 键盘上,meta 被标记为 “META” 或者 “Meta”。

例子,同时鼠标左击和按 ctrl 弹出提示:

<!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>syl-vue-test</title>
    <!-- 引入 vue.js -->
    <script src="vue.min.js"></script>
  </head>
  <body>
    <div id="app">
      <!-- 同时鼠标左击和按 ctrl 弹出提示 -->
      <div @click.ctrl="alert('你同时按了鼠标点击和ctrl')">Do something</div>
    </div>
    <script>
      var app = new Vue({
        el: "#app",
      });
    </script>
  </body>
</html>

.exact

.exact 精确按键修饰符,允许你控制由精确的系统修饰符组合触发的事件。

<!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>syl-vue-test</title>
    <!-- 引入 vue.js -->
    <script src="vue.min.js"></script>
  </head>
  <body>
    <div id="app">
      <!-- 即使 Alt 或 Shift 被一同按下时也会触发 -->
      <button
        @click.ctrl="alert('你不单单只按了鼠标左键和 Ctrl键,同时按其他键我也可以触发')"
      >
        A
      </button>

      <!-- 有且只有 ctrl 键 + 鼠标左键 被按下的时候才触发 -->
      <button @click.ctrl.exact="alert('你只按ctrl键+鼠标左键,才能触发我')">
        A
      </button>

      <!-- 没有任何系统修饰符被按下的时候才触发 -->
      <button @click.exact="alert('没有按任何系统修饰符')">A</button>
    </div>
    <script>
      var app = new Vue({
        el: "#app",
      });
    </script>
  </body>
</html>

鼠标按钮修饰符

这些修饰符会限制处理函数仅响应特定的鼠标按钮。

  • .left
  • .right
  • .middle
<!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>syl-vue-test</title>
    <!-- 引入 vue.js -->
    <script src="vue.min.js"></script>
  </head>
  <body>
    <div id="app">
      <button @click.left="alert('你按了鼠标左击键')">按钮</button>
      <button @click.middle="alert('你按了鼠标滚轮')">按钮</button>
      <button @click.right="alert('你按了鼠标右击键')">按钮</button>
    </div>
    <script>
      var app = new Vue({
        el: "#app",
      });
    </script>
  </body>
</html>

综合小练习

小游戏(500px),一直鼠标左键,将小球向右移 500px,拼手速的哦:

<!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>syl-vue-test</title>
    <!-- 引入 vue.js -->
    <script src="vue.min.js"></script>
    <style>
      * {
        padding: 0;
        margin: 0;
      }
      #app {
        position: relative;
        width: 500px;
        height: 100px;
        background: black;
      }
      .box {
        position: absolute;
        left: 0;
        top: 0;
        width: 100px;
        height: 100px;
        border-radius: 50%;
        background: red;
        transition: all 0.3s ease-in;
      }
    </style>
  </head>
  <body>
    <div id="app" @click.left="changePosition">
      <div class="box" :style="{left:left+'px'}"></div>
    </div>
    <script>
      var app = new Vue({
        el: "#app",
        data: {
          left: 0,
        },
        methods: {
          changePosition: function () {
            this.left += 25;
            if (this.left >= 500) {
              alert("走了500px了");
              this.left = 0;
            }
          },
        },
      });
    </script>
  </body>
</html>

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值