详解Vue之事件处理


Posted in Javascript onJuly 10, 2020

在Vue进行前端开发中,事件监听是必不可少的功能,本文通过简单的小例子,简述v-on的简单用法,仅供学习分享使用,如有不足之处,还请指正。

监听事件

可以用 v-on 指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码。如下所示:

<button v-on:click="counter += 1">Add 1</button>
 <p>按钮被点击了 {{ counter }} 次.</p>

其中counter为Vue自定义的一个属性值。

事件处理方法

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

<button v-on:click="greet">Greet</button>

greet 是在下面定义的方法名。如下所示:

<script type="text/javascript">
 var app=new Vue({
  el:'#app',
  data:{
   msg:'hello world!!!',
   counter:0,
   name: 'Vue.js'
  },
  // 在 `methods` 对象中定义方法
  methods:{
   greet: function (event) {
    // `this` 在方法里指向当前 Vue 实例
    alert('Hello ' + this.name + '!')
     // `event` 是原生 DOM 事件
    if (event) {
     alert(event.target.tagName)
    }
   },

  }
 });
</script>

内联处理器中的方法

除了直接绑定到一个方法,也可以在内联 JavaScript 语句中调用方法,如下所示:

<button v-on:click="say('hi')">Say hi</button> 
<button v-on:click="say('what')">Say what</button>

有时也需要在内联语句处理器中访问原始的 DOM 事件。可以用特殊变量 $event 把它传入方法:

<button v-on:click="warn('表单不能被提交.', $event)">提交</button>

其中say,warn均为自定义方法,如下所示:

say: function (message) {
 alert(message);
},
warn: function (message, event) {
 // 现在我们可以访问原生事件对象
 if (event) {
  event.preventDefault();
 }
 alert(message);
}

事件修饰符

在事件处理程序中调用 event.preventDefault() 或 event.stopPropagation() 是非常常见的需求。尽管我们可以在方法中轻松实现这点,但更好的方式是:方法只有纯粹的数据逻辑,而不是去处理 DOM 事件细节。为了解决这个问题,Vue.js 为 v-on 提供了事件修饰符。之前提过,修饰符是由点开头的指令后缀来表示的。事件修饰符共以下几种:

  • .stop
  • .prevent
  • .capture
  • .self
  • .once
  • .passive
<!-- 阻止单击事件继续传播 -->
<a v-on:click.stop="doThis">点击666</a>
<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit">
 <div>阻止提交</div>
</form>
<!-- 修饰符可以串联 -->
<a v-on:click.stop.prevent="doThat"></a>
<!-- 只有修饰符 -->
<form v-on:submit.prevent>
 <div id="d">只有修饰符</div>
</form>
<!-- 添加事件监听器时使用事件捕获模式 -->
<!-- 即内部元素触发的事件先在此处理,然后才交由内部元素进行处理 -->
<div v-on:click.capture="doThis">doThis...</div>
<!-- 只当在 event.target 是当前元素自身时触发处理函数 -->
<!-- 即事件不是从内部元素触发的 -->
<div v-on:click.self="doThat">doThat...</div>

使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用 v-on:click.prevent.self 会阻止所有的点击,而 v-on:click.self.prevent 只会阻止对元素自身的点击。

新增属性

不像其它只能对原生的 DOM 事件起作用的修饰符,.once 修饰符还能被用到自定义的组件事件上。

<!-- 点击事件将只会触发一次 -->
<a v-on:click.once="doThis">点我一次666</a>

Vue 还对应 addEventListener 中的 passive 选项提供了 .passive 修饰符。

<!-- 滚动事件的默认行为 (即滚动行为) 将会立即触发 -->
<!-- 而不会等待 `onScroll` 完成 -->
<!-- 这其中包含 `event.preventDefault()` 的情况 -->
<div v-on:scroll.passive="onScroll">...</div>

这个 .passive 修饰符尤其能够提升移动端的性能。不要把 .passive 和 .prevent 一起使用,因为 .prevent 将会被忽略,同时浏览器可能会向你展示一个警告。请记住,.passive 会告诉浏览器你不想阻止事件的默认行为。

按键修饰符

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

<!-- 只有在 `key` 是 `Enter` 时调用 `vm.submit()` ,点击时不调用 -->
 <input v-on:keyup.enter="submit" type="text" value="点我777" />
 <!-- 可以直接将 KeyboardEvent.key 暴露的任意有效按键名转换为 kebab-case 来作为修饰符。-->
 <input v-on:keyup.page-down="onPageDown" type="text" value="点我888" />
 <!-- 在上述示例中,处理函数只会在 $event.key 等于 PageDown 时被调用。且光标在时才管用。 -->

系统修饰符

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

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

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

<!-- Alt + C -->
 <input @keyup.alt.67="clear">
 
 <!-- Ctrl + Click -->
 <div @click.ctrl="doSomething">Do something</div>

请注意:修饰键与常规按键不同,在和 keyup 事件一起用时,事件触发时修饰键必须处于按下状态。换句话说,只有在按住 ctrl 的情况下释放其它按键,才能触发 keyup.ctrl。而单单释放 ctrl 也不会触发事件。如果你想要这样的行为,请为 ctrl 换用 keyCode:keyup.17。

.exact 修饰符

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

<!-- 即使 Alt 或 Shift 被一同按下时也会触发 -->
 <button @click.ctrl="onClick">A</button>
 <!-- 有且只有 Ctrl 被按下的时候才触发 -->
 <button @click.ctrl.exact="onCtrlClick">A</button>
 <!-- 没有任何系统修饰符被按下的时候才触发 -->
 <button @click.exact="onClick">A</button>

鼠标按钮修饰符

这些修饰符会限制处理函数仅响应特定的鼠标按钮,如下所示:

  • .left
  • .right
  • .middle

为什么在 HTML 中监听事件?

你可能注意到这种事件监听的方式违背了关注点分离 (separation of concern) 这个长期以来的优良传统。但不必担心,因为所有的 Vue.js 事件处理方法和表达式都严格绑定在当前视图的 ViewModel 上,它不会导致任何维护上的困难。实际上,使用 v-on 有几个好处:

  • 扫一眼 HTML 模板便能轻松定位在 JavaScript 代码里对应的方法。
  • 因为你无须在 JavaScript 里手动绑定事件,你的 ViewModel 代码可以是非常纯粹的逻辑,和 DOM 完全解耦,更易于测试。
  • 当一个 ViewModel 被销毁时,所有的事件处理器都会自动被删除。你无须担心如何清理它们。

本例中全部代码如下所示:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>事件处理</title>
    <!-- 开发环境版本,包含了有帮助的命令行警告 -->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  </head>
  <body>
    <div id="app">
      <h2>监听事件</h2>
      <!--
       可以用 v-on 指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码。
       -->
      <button v-on:click="counter += 1">Add 1</button>
      <p>按钮被点击了 {{ counter }} 次.</p>
      <h2>事件处理方法</h2>
      <!--
       然而许多事件处理逻辑会更为复杂,所以直接把 JavaScript 代码写在 v-on 指令中是不可行的。
       因此 v-on 还可以接收一个需要调用的方法名称。
       -->
      <!-- `greet` 是在下面定义的方法名 -->
      <button v-on:click="greet">Greet</button>
      <!--
       // 也可以用 JavaScript 直接调用方法
       //app.greet() // => 'Hello Vue.js!'
       -->
       <h2>内联处理器中的方法</h2>
       <!--
       除了直接绑定到一个方法,也可以在内联 JavaScript 语句中调用方法:
       -->
      <button v-on:click="say('hi')">Say hi</button>
      <button v-on:click="say('what')">Say what</button>
      <!--
      有时也需要在内联语句处理器中访问原始的 DOM 事件。可以用特殊变量 $event 把它传入方法:
       -->
       <br>
       <button v-on:click="warn('表单不能被提交.', $event)">提交</button>
       <h2>事件修饰符</h2>
       <!--
       在事件处理程序中调用 event.preventDefault() 或 event.stopPropagation() 是非常常见的需求。
       尽管我们可以在方法中轻松实现这点,但更好的方式是:方法只有纯粹的数据逻辑,而不是去处理 DOM 事件细节。
       为了解决这个问题,Vue.js 为 v-on 提供了事件修饰符。之前提过,修饰符是由点开头的指令后缀来表示的。
       .stop
      •.prevent
      •.capture
      •.self
      •.once
      •.passive
       -->
      <!-- 阻止单击事件继续传播 -->
      <a v-on:click.stop="doThis">点击666</a>
      <br>
      <!-- 提交事件不再重载页面 -->
      <form v-on:submit.prevent="onSubmit">
        <div>
          阻止提交
        </div>
      </form>
      <br>
      <!-- 修饰符可以串联 -->
      <a v-on:click.stop.prevent="doThat"></a>
      <br>
      <!-- 只有修饰符 -->
      <form v-on:submit.prevent>
        <div id="d">
          只有修饰符
        </div>
      </form>
      <br>
      <!-- 添加事件监听器时使用事件捕获模式 -->
      <!-- 即内部元素触发的事件先在此处理,然后才交由内部元素进行处理 -->
      <div v-on:click.capture="doThis">doThis...</div>
      <br>
      <!-- 只当在 event.target 是当前元素自身时触发处理函数 -->
      <!-- 即事件不是从内部元素触发的 -->
      <div v-on:click.self="doThat">doThat...</div>
      <!--
      使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。
      因此,用 v-on:click.prevent.self 会阻止所有的点击,而 v-on:click.self.prevent 只会阻止对元素自身的点击。
       -->
      <h2>新增</h2>
      <!-- 点击事件将只会触发一次 -->
      <a v-on:click.once="doThis">点我一次666</a>
      <!--
       不像其它只能对原生的 DOM 事件起作用的修饰符,.once 修饰符还能被用到自定义的组件事件上。
       -->
       <!--
       Vue 还对应 addEventListener 中的 passive 选项提供了 .passive 修饰符。
       -->
      <!-- 滚动事件的默认行为 (即滚动行为) 将会立即触发 -->
      <!-- 而不会等待 `onScroll` 完成 -->
      <!-- 这其中包含 `event.preventDefault()` 的情况 -->
      <div v-on:scroll.passive="onScroll">...</div>
      <!--
      这个 .passive 修饰符尤其能够提升移动端的性能。
      !不要把 .passive 和 .prevent 一起使用,因为 .prevent 将会被忽略,同时浏览器可能会向你展示一个警告。
      请记住,.passive 会告诉浏览器你不想阻止事件的默认行为。
       -->
       <h2>按键修饰符</h2>
       <!--
       在监听键盘事件时,我们经常需要检查详细的按键。Vue 允许为 v-on 在监听键盘事件时添加按键修饰符:
       -->
      <!-- 只有在 `key` 是 `Enter` 时调用 `vm.submit()` ,点击时不调用 -->
      <input v-on:keyup.enter="submit" type="text" value="点我777" />
      <!--
       可以直接将 KeyboardEvent.key 暴露的任意有效按键名转换为 kebab-case 来作为修饰符。
       -->
       <input v-on:keyup.page-down="onPageDown" type="text" value="点我888" />
       <!--
       在上述示例中,处理函数只会在 $event.key 等于 PageDown 时被调用。且光标在时才管用。
       -->
       <h2>#按键码</h2>
      <!--
      keyCode 的事件用法已经被废弃了并可能不会被最新的浏览器支持。 使用 keyCode attribute 也是允许的:
       -->
      <input v-on:keyup.13="submit" type="button" value="key up 13">
      <!--
       为了在必要的情况下支持旧浏览器,Vue 提供了绝大多数常用的按键码的别名:
       .enter
      •.tab
      •.delete (捕获“删除”和“退格”键)
      •.esc
      •.space
      •.up
      •.down
      •.left
      •.right
      !有一些按键 (.esc 以及所有的方向键) 在 IE9 中有不同的 key 值, 如果你想支持 IE9,这些内置的别名应该是首选。
      你还可以通过全局 config.keyCodes 对象自定义按键修饰符别名:
      // 可以使用 `v-on:keyup.f1`
      Vue.config.keyCodes.f1 = 112
       -->
       <h2>系统修饰键</h2>
       <!--
       可以用如下修饰符来实现仅在按下相应按键时才触发鼠标或键盘事件的监听器。
       .ctrl
      •.alt
      •.shift
      •.meta
      注意:在 Mac 系统键盘上,meta 对应 command 键 (⌘)。
      在 Windows 系统键盘 meta 对应 Windows 徽标键 (⊞)。在 Sun 操作系统键盘上,meta 对应实心宝石键 (◆)。
      在其他特定键盘上,尤其在 MIT 和 Lisp 机器的键盘、以及其后继产品,比如 Knight 键盘、space-cadet 键盘,meta 被标记为“META”。
      在 Symbolics 键盘上,meta 被标记为“META”或者“Meta”。
       -->
      <!-- Alt + C -->
      <input @keyup.alt.67="clear">

      <!-- Ctrl + Click -->
      <div @click.ctrl="doSomething">Do something</div>
      <!--
      !请注意修饰键与常规按键不同,在和 keyup 事件一起用时,事件触发时修饰键必须处于按下状态。
      换句话说,只有在按住 ctrl 的情况下释放其它按键,才能触发 keyup.ctrl。而单单释放 ctrl 也不会触发事件。
      如果你想要这样的行为,请为 ctrl 换用 keyCode:keyup.17。
       -->
      <h2>#.exact 修饰符</h2>
      <!--
       .exact 修饰符允许你控制由精确的系统修饰符组合触发的事件。
       -->
       <!-- 即使 Alt 或 Shift 被一同按下时也会触发 -->
      <button @click.ctrl="onClick">A</button>

      <!-- 有且只有 Ctrl 被按下的时候才触发 -->
      <button @click.ctrl.exact="onCtrlClick">A</button>

      <!-- 没有任何系统修饰符被按下的时候才触发 -->
      <button @click.exact="onClick">A</button>
      <h2>#鼠标按钮修饰符</h2>
      <!--
       .left
      •.right
      •.middle

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

       -->
       <h2>为什么在 HTML 中监听事件?</h2>
       <!--
       你可能注意到这种事件监听的方式违背了关注点分离 (separation of concern) 这个长期以来的优良传统。
       但不必担心,因为所有的 Vue.js 事件处理方法和表达式都严格绑定在当前视图的 ViewModel 上,它不会导致任何维护上的困难。
       实际上,使用 v-on 有几个好处:
      1.扫一眼 HTML 模板便能轻松定位在 JavaScript 代码里对应的方法。
      2.因为你无须在 JavaScript 里手动绑定事件,你的 ViewModel 代码可以是非常纯粹的逻辑,和 DOM 完全解耦,更易于测试。
      3.当一个 ViewModel 被销毁时,所有的事件处理器都会自动被删除。你无须担心如何清理它们。
       -->
    </div>
    <script type="text/javascript">
      var app=new Vue({
        el:'#app',
        data:{
          msg:'hello world!!!',
          counter:0,
          name: 'Vue.js'
        },
        // 在 `methods` 对象中定义方法
        methods:{
          greet: function (event) {
           // `this` 在方法里指向当前 Vue 实例
           alert('Hello ' + this.name + '!')
           // `event` 是原生 DOM 事件
           if (event) {
            alert(event.target.tagName)
           }
          },
          say: function (message) {
           alert(message);
          },
          warn: function (message, event) {
            // 现在我们可以访问原生事件对象
            if (event) {
             event.preventDefault();
            }
            alert(message);
          },
          doThis:function(){
            alert('点我666');
          },
          doThat:function(){
            alert('点它666');
          },
          submit:function(){
            alert('点我--submit');
          },
          onPageDown:function(){
            alert('点我--onPageDown');
          },
          doSomething:function(){
            alert('点我--doSomething');
          },
          clear:function(){
            alert('点我--clear');
          },
          onClick:function(){
            alert('点我--onClick');
          },
          onCtrlClick:function(){
            alert('点我--onCtrlClick');
          }
        }
      });
    </script>
  </body>
</html>

以上就是详解Vue之事件处理的详细内容,更多关于Vue之事件处理的资料请关注三水点靠木其它相关文章!

Javascript 相关文章推荐
Dojo之路:如何利用Dojo实现Drag and Drop效果
Apr 10 Javascript
js中 关于undefined和null的区别介绍
Apr 16 Javascript
常用的几段javascript代码分享
Mar 25 Javascript
JS正则表达式比较常见用法
Jan 26 Javascript
微信小程序 slider 详解及实例代码
Jan 10 Javascript
jQuery基本选择器和层次选择器学习使用
Feb 27 Javascript
微信小程序扫描二维码获取信息实例详解
May 07 Javascript
微信小程序class封装http代码实例
Aug 24 Javascript
js构造函数constructor和原型prototype原理与用法实例分析
Mar 02 Javascript
vue如何在用户要关闭当前网页时弹出提示的实现
May 31 Javascript
uni-app实现获取验证码倒计时功能
Nov 01 Javascript
Vue如何跨组件传递Slot的实现
Dec 14 Vue.js
jQuery开发仿QQ版音乐播放器
Jul 10 #jQuery
Element图表初始大小及窗口自适应实现
Jul 10 #Javascript
Vue路由切换页面不更新问题解决方案
Jul 10 #Javascript
简单了解Vue computed属性及watch区别
Jul 10 #Javascript
通过实例解析chrome如何在mac环境中安装vue-devtools插件
Jul 10 #Javascript
基于vue+element实现全局loading过程详解
Jul 10 #Javascript
JS sort方法基于数组对象属性值排序
Jul 10 #Javascript
You might like
php的dl函数用法实例
2014/11/06 PHP
PHP curl 或 file_get_contents 获取需要授权页面的方法
2017/05/05 PHP
禁止JQuery中的load方法装载IE缓存中文件的方法
2009/09/11 Javascript
web页面数据展示新想法(json)
2010/06/08 Javascript
range 标准化之获取
2011/08/28 Javascript
jQuery异步加载数据并添加事件示例
2014/08/24 Javascript
jQuery右下角旋转环状菜单特效代码
2015/08/10 Javascript
js实现的页面矩阵图形变换特效
2016/01/26 Javascript
学习使用bootstrap3栅格系统
2016/04/12 Javascript
BootStrap入门教程(三)之响应式原理
2016/09/19 Javascript
浅述节点的创建及常见功能的实现
2016/12/15 Javascript
配置nodejs环境的方法
2017/05/13 NodeJs
Jquery把获取到的input值转换成json
2017/05/15 jQuery
vue axios 给生产环境和发布环境配置不同的接口地址(推荐)
2018/05/08 Javascript
微信小程序获取用户绑定手机号方法示例
2019/07/21 Javascript
element实现合并单元格通用方法
2019/11/13 Javascript
vue中的过滤器及其时间格式化问题
2020/04/09 Javascript
[01:30:55]VG vs Mineski Supermajor 败者组 BO3 第三场 6.6
2018/06/07 DOTA
[01:04:39]OG vs Mineski 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/18 DOTA
Python中property函数用法实例分析
2018/06/04 Python
Python简单爬虫导出CSV文件的实例讲解
2018/07/06 Python
Python 装饰器@,对函数进行功能扩展操作示例【开闭原则】
2019/10/17 Python
YUV转为jpg图像的实现
2019/12/09 Python
Numpy中np.random.rand()和np.random.randn() 用法和区别详解
2020/10/23 Python
美国杂志订阅折扣与优惠网站:Magazines.com
2016/08/31 全球购物
Smallable英国家庭概念店:设计师童装及家居装饰
2017/07/05 全球购物
美国演唱会和体育门票购买网站:Ticketnetwork
2018/10/19 全球购物
2013英文求职信模板范文
2013/11/15 职场文书
财务会计专业推荐信
2013/11/30 职场文书
财务管理职业生涯规划范文
2013/12/27 职场文书
2014最新开业庆典策划方案(5篇)
2014/09/15 职场文书
三潭印月的导游词
2015/02/12 职场文书
2015新学期开学寄语
2015/02/26 职场文书
小区保洁员岗位职责
2015/04/10 职场文书
学会感恩主题班会
2015/08/12 职场文书
vue-cli4.5.x快速搭建项目
2021/05/30 Vue.js