Vue 2.0学习笔记:v-on

发布于 大漠

JavaScript在浏览器中以单线程模式运行,页面加载后,一旦页面上所有的JavaScript代码被执行完后,就只能依赖触发事件来执行JavaScript代码。浏览器在接收到用户的鼠标或键盘输入后,会自动在对应的DOM节点上触发相应的事件。如果该节点已经绑定了对应的JavaScript处理函数,该函数就会自动调用。

在我们平常经常能看到这样的一些例子:

  • 当用户点击鼠标时
  • 当页面加载时
  • 当图像已加载时
  • 当鼠标移动到元素上时
  • 当输入字段被改变时
  • 当提交HTML表单时
  • 当用户触发按键时

在使用Vue开发项目时,我们同样逃脱不了一些事件,那么这一节我们就一起来看看怎么在Vue中给元素或组件绑定一些事件。在学习Vue中的相关知识之前,咱们先简单的回忆一些JavaScript相关的知识。

JavaScript中事件相关知识

在JavaScript中任何一个DOM元素都有其自身存在的事件对象。事件对象代表事件的状态,比如事件在其中发生的元素、键盘按键的状态、鼠标的位置和鼠标按钮的状态等。事件通常与函数结合使用,函数不会在事件发生前被执行。

在JavaScript中常见的事件句柄(Event Handlers)主要有:

属性名 描述(对应事件发生在何时...) 属性名 描述(对应事件发生在何时...)
onabort 图像的加载被中断 onblur 元素失去焦点
onchange 域的内容被改变 onclick 当用户点击某个对象时调用的事件名柄
ondblclick 当用户双击某个对象时调用的事件句柄 onerror 在加载文档或图像时发生错误
onfocus 元素获得焦点 onkeydown 某个键盘按键被按下
onkeypress 某个键盘按键被按下并松开 onkeyup 某个键盘按键被松开
onload 一张页面或一幅图像完成加载 onmousemove 鼠标按钮被按下
onmousemove 鼠标被移动 onmouseout 鼠标从某个元素移开
onmouseover 鼠标移动到某元素之上 onmouseup 鼠标铵键被松开
onreset 重置按钮被点击 onresize 窗口或框架被重新调整大小
onselect 文本被选中 onsubmit 确认按钮被点击
onunload 用户退出页面    

上表格中这些事件句柄,我们可以写在HTML元素中,也就当作HTML元素的属性,比如:

<!-- HTML -->
<h1 onclock="clickEvent">点击我</h1>

// JavaScript
function clickEvent() {
    alert('点我,我就出来了')
}

这个时候效果如下:

v-on

但在我们的JavaScript文件中,对于onclick通过使用click来替换,比如上面的示例,我们换成这样的代码:

<!-- HTML -->
<h1>点击我</h1>

// JavaScript

function clickEvent() {
    alert('点我,我就出来了')
}

let ele = document.querySelector('h1')

ele.addEventListener('click', clickEvent, false)

他们得到的效果是一样的。

有关于这方面的知识,建议阅读下面的一些文章:

Vue中的 v-on

事件是每个框架都绕不过去的话题,实现的方式各有千秋,在Vue中,我们通过v-on的指令来进行事件监听。在Vue中绑定事件监听器。事件类型由参数指定。表达式可以是一个方法的名字或一个内联语句,如果没有修饰符也可以省略。

v2.4.0开始v-on同样支持不带参数绑定一个事件/监听器键值对的对象。注意当使用对象语法时,是不支持任何修饰器的。

用在普通元素上时,只能监听 原生DOM事件。用在自定义元素组件上时,也可以监听子组件触发的自定义事件

在监听原生DOM事件时,方法以事件为唯一的参数。如果使用内联语句,语句可以访问一个$event属性:v-on:click="handle('ok', $event)"

先来看一个简单的示例,比如文章开头的示例,我们在Vue中应该怎么写。

<!-- Template -->
<div id="app">
    <h1 v-on:click="clickMe">点击我</h1>   
</div>

// JavaScript
var app = new Vue({
    el: '#app',
    methods: {
        clickMe: function() {
            alert("点击我,我就出来了!(^_^)")
        }
    },
    data: {
        
    }
})

看到的效果如下:

v-on

从效果上看,和JavaScript中的原生效果是一样的。咱们回到Vue的世界中来。

在Vue的模板中,我们使用了v-on,并且绑定了一个click事件(v-on:click),然后给这个click事件绑定了一个事件clickMe。而这个clickMe在Vue中,我们一般是放在methods: {}中,也就是说clickMe这个函数写在methods中。至于methods起什么作用,咱们先不说,后面我们会有一节内容专门来介绍这个知识点。

看到v-on:click="clickMe",大家可能会看到我们在HTML中的onclock="clickEvent"。是不是非常的相似。从外表现象看,他们写法不一样,但是起到的结果是一致的。在Vue中,我们还可以使用@click来替代v-on:click。那么他们起到的作用是一样的。

在Vue中,对于v-on的使用方式,除了上面的示例展示之外,还有下面这些使用方式:

<!-- 方法处理器 -->
<button v-on:click="clickMe"></button>

<!-- 对象语法 (v2.4.0版本以上才支持) -->
<button v-on="{ mousedown: doThis, mouseup: doThat}"></button>

<!-- 内联语句 -->
<button v-on:click="doThat('Hello', $event)"></button>

<!-- 缩写 -->
<button @click="doThis"></button>

<!-- 停止冒泡 -->
<button @click.stop="doThis"></button>

<!-- 阻止默认行为 -->
<button @click.prevent="doThis"></button>

<!-- 阻止默认行为, 没有表达式 -->
<form @submit.prevent></form>

<!-- 串联修饰符 -->
<button @click.stop.prevent="doThis"></button>

<!-- 键修饰符, 键别名 -->
<input @keyup.13="onEnter" />

<!-- 点击回调只会触发一次 -->
<button v-on:click.once="doThis"></button>

在子组件上监听自定义事件(当子组件触发my-event时将调用事件处理器):

<my-component @my-event="handleThis"></my-component>
<!-- 内联语句 -->
<my-component @my-event="handleThis(123, $event)"></my-component>
<!-- 组件中的原生事件 -->
<my-component @click.native="onClick"></my-component>

从上面的简单示例中,可以看出Vue在事件处理的过程中自带了一些修饰符:

  • .stop:调用event.stopPropagation()
  • .prevent:调用event.preventDefault()
  • .capture:添加事件侦听器时使用capture模式
  • .self:只当事件是从侦听器绑定的元素本身触发时才触发回调
  • .{keyCode | keyAlias}:只当事件是从特定键触发时才触发回调
  • .native:监听组件根元素的原生事件
  • .once:只触发一次回调
  • .left:只当点击鼠标左键时触发,(v2.2.0+ 才具有)
  • .right:只当点击鼠标右键时触发,(v2.2.0+ 才具有)
  • .middle:只当点击鼠标中键时触发,(v2.2.0+ 才具有)
  • .passive:以{passive: true}模式添加侦听器,(v2.3.0+ 才具有)

Vue的官网对事件的处理和组件的自定义的事件都有详细的介绍。如果感兴趣的话,可以查看相应的内容:

v-on示例

我们来做一个简单的效果,就是一个计数器,效果如下:

这个效果很简单,点击+数字往下加,点击-数字往下减。在Vue中,我们的模板中有三个元素,两个按钮,一个显示数字的容器,第一个按钮做加的计算,第二个按钮做减的计数。简单的结构如下所示:

<div id="app">
    <button v-on:click="increase">+</button>
    <span>{{ count }}</span>
    <button v-on:click="reduce">-</button>
</div>

两个按钮上都绑定了一个click事件,点击按钮分别触发increasereduce两个函数,前者做加法,后者做减法。另外一个元素中我们有一个值{{ count }}。每次点击按钮这个{{ count }}都会做相应的变化。如果你接触过前面的内容,知道{{}}在Vue中是属性文本插值,如果你没有接触过,可以阅读上一篇文章《v-textv-html》。

模板有了之后,需要添加对应的功能。

let app = new Vue({
    el: '#app',
    methods: {
        increase: function() {
            this.count++
        },
        reduce: function() {
            this.count--
        }
    },
    data: {
        count: 0
    }
})

在Vue中,我们在methods中声明了两个函数,分别是increase(加法)和reduce(减法)。另外需要在数据源中声明count。对于这么简单的效果,我们也可以直接在v-on中处理完:

<button v-on:click="count += 1">+</button>

比如我们前面的示例,修改之后的效果如下:

最终看到的效果是一致的。但实际上,许多事件处理的逻辑都很复杂,所以直接把JavaScript代码写在v-on指令中是不可行的。因此v-on接收一个定义的方法才更适合我们平常的开发模式。比如我们一开始看到的示例。

上面看到的示例都是click的事件,其实其他的事件也是一样的使用方式,比如我们要实现一个mousemove的效果,那么我们可以使用v-on:mousemove=""或者使用@mousemove即可。如果你感兴趣的话,可以自己动手一试。

总结

这篇文章主要学习了Vue中的v-on指令。这个指令是用来给DOM元素绑定事件,通过这个指令,咱们可以很好的在Vue中的DOM绑定事件,实现一些功能性的操作。比如文章中的示例,点击加号按钮做加法计数。同时,Vue中对一些事件还提供了一些修饰符的功能,比如.stop用来阻止事件冒泡之类的。

在Vue我们可以直接在v-on写一些简单的功能,也可以使用一些内联的功能,但对于一些复杂的功能,还是需要借助Vue的methods的特性,将事件对应的功能都放置在methods: {}中。这样更易于维护,也可以写一些复杂的功能。

由于作者自已是一位Vue的初学者,如果文章中有何不对之处,还请各位大婶拍正。如果你有更好的经验,欢迎在下面的评论中与我们一起分享。

大漠

常用昵称“大漠”,W3CPlus创始人,目前就职于手淘。对HTML5、CSS3和Sass等前端脚本语言有非常深入的认识和丰富的实践经验,尤其专注对CSS3的研究,是国内最早研究和使用CSS3技术的一批人。CSS3、Sass和Drupal中国布道者。2014年出版《图解CSS3:核心技术与案例实战》。

如需转载,烦请注明出处:https://www.fedev.cn/vue/v-on.htmlnike air max 1 edition