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('点我,我就出来了')
}
这个时候效果如下:
但在我们的JavaScript文件中,对于onclick
通过使用click
来替换,比如上面的示例,我们换成这样的代码:
<!-- HTML -->
<h1>点击我</h1>
// JavaScript
function clickEvent() {
alert('点我,我就出来了')
}
let ele = document.querySelector('h1')
ele.addEventListener('click', clickEvent, false)
他们得到的效果是一样的。
有关于这方面的知识,建议阅读下面的一些文章:
- 事件模型
- Event
- 事件
- 漫谈JS自定义事件、DOM/伪DOM自定义事件
- JavaScript事件轮询
- 监控事件
- Understanding Javascript Events In Depth
- What Is Event Bubbling in JavaScript? Event Propagation Explained
- JavaScript Events 101
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: {
}
})
看到的效果如下:
从效果上看,和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
事件,点击按钮分别触发increase
和reduce
两个函数,前者做加法,后者做减法。另外一个元素中我们有一个值{{ count }}
。每次点击按钮这个{{ count }}
都会做相应的变化。如果你接触过前面的内容,知道{{}}
在Vue中是属性文本插值,如果你没有接触过,可以阅读上一篇文章《v-text
和v-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的初学者,如果文章中有何不对之处,还请各位大婶拍正。如果你有更好的经验,欢迎在下面的评论中与我们一起分享。
如需转载,烦请注明出处:https://www.w3cplus.com/vue/v-on.html