可以用 v-on 指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码。v-on: 可以使用 @ 来代替,两者作用都相同
v-on 指令不能直接绑定,后面需要指定一个事件类型以及需要调用的方法名称,例如 click、input 事件类型
事件需要调用的方法名称定义在 methods 选项中,方法中的 this 指向实例对象,不要使用箭头函数会改变 this 指向
在
Vue中,调用的方法可以直接使用方法名调用,也可以加上()形式,在参数时调用必须加上()调用,在Mustache标签{{}}内必须以()形式调用
<h3>{{title}}</h3>
<!-- 可以通过v-on:或者@绑定事件监听 -->
<button type="button" v-on:click="changeValue">修改内容</button>
<!-- <button type="button" @click="changeValue"></button> -->
el: '#app',
data: function() {
return {
title: 'hello vue'
}
},
methods: {
// 在methods选项中定义事件触发的回调函数
changeValue() {
// 不要使用箭头函数箭头函数会改变this
console.log(this); // this指向实例
console.log(vm === this); // true
this.title = 'Hello JSX'
}
}
v-on 后面接收一个需要调用的方法名称,通过 v-on 绑定的事件类型触发时调用JavaScript 语句中通过 () 调用方法以及传入参数调用$event 访问原始的 DOM 事件
@click="func" 不带括号、不写实参的函数默认传 event (事件对象)@click="func(val)" 只要加括号,无论是否传值,都属于传实参给函数,event (事件对象)无法接收@click="func($event, val)" 如果需要实参、又需要 event (事件对象),就需要手动传入 event (事件对象)可以在定义方法中获取
event对象,event对象代表事件的状态,例如事件在其中发生的元素、键盘按键、的状态、鼠标的位置、鼠标按键的状态。当一个事件发生的时候,和当前这个对象发生的这个事件有关的信息都会被临时保存到event对象。对象在执行事件时,浏览器通过函数传递过来
<h3>{{title}}</h3>
<!-- 不带参数默认传入event -->
<button type="button" @click="changeValue">changeValue</button>
<!-- 加括号传入无论是否传参 event对象无法接收 -->
<button type="button" @click="changeTitle('Hello JavaScript')">changeTitle</button>
<!-- 需要实参需要event对象,手动传入event -->
<button type="button" @click="changeMessage($event, 'Hello Ljj')">changeTitle</button>
el: '#app',
data: function() {
return {
title: 'Hello Vue'
}
},
methods: {
changeValue(e) {
this.title = 'Hello JSX'
console.log(e);
},
changeTitle(message) {
this.title = message
},
changeMessage(event, val) {
console.log(event); // 此时参数为DOM事件对象
this.title = val
}
}
在使用事件时通常需要某些限制,例如阻止事件冒泡、阻止默认事件等等,Vue 为解决这种事件限制提供了特点的语法 ——— 事件修饰符
修饰符是由点开头的指令后缀来表示的 v-on:事件.修饰符
.stop —— 相当于 js 中的 event.stopPropagation() 阻止事件冒泡.prevent —— 相当于 js 中的 event.preventDefault() 阻止默认事件.capture —— 与事件冒泡相反,事件捕获由外到内.self —— 只会触发自己范围内的事件.once —— 只会触发一次.passive —— 执行默认行为.stop 修饰符用来阻止事件冒泡
事件冒泡:当一个事件发生在一个元素上,它会首先运行在该元素上的处理程序,然后运行其父元素上的处理程序,然后一直向上到其他祖先上的处理程序
<!-- .stop修饰符用于阻止冒泡行为 -->
<div class="father" @click="funcEvent('父元素-触发')">father
<div class="son" @click.stop="funcEvent('子元素-触发')">stop</div>
<!-- 点击h3触发冒泡父元素也会触发事件 -->
<!-- 设置.stop阻止冒泡 -->
</div>
el: '#app',
methods: {
funcEvent(val) {
console.log(val)
}
}
.prevent 修饰符用于阻止默认行为,例如阻止超链接标签跳转等
不要把
.passive和.prevent一起使用,因为.prevent将会被忽略,同时浏览器可能会向你展示一个警告。.passive会告诉浏览器你不想阻止事件的默认行为
<!-- 超链接阻止默认跳转 -->
<a href="https://www.baidu.com" @click.prevent>百度</a>
<!-- 阻止表单默认提交事件 -->
<form action="">
<input type="submit" value="submit提交" @click.prevent>
</form>
<!-- .passive与.prevent一起使用 .prevent会失效 -->
<button type="button" @click.passive="func">不阻止默认事件</button>
el: '#app',
methods: {
funcEvent(e) {
e.preventDefault();
console.log('不阻止默认事件')
// Unable to preventDefault inside passive event listener invocation.
}
}
.caption 修饰符是用于事件捕获,与事件冒泡是一对相反的事件流程,当想要将页面元素事件流改为捕获模式时,只要在父元素的事件上绑定 .caption 修饰符即可
事件捕获:事件首先由 document 捕获,然后沿 DOM 树依次向下传播,直到到达实际的目标元素
<!-- .capture捕获模式 -->
<div class="father" @click.capture="funcEvent('父元素-触发')">father
<div class="son" @click.capture="funcEvent('子元素-触发')">capture</div>
<!-- 点击h3捕获从外到内先响应外层父元素事件 -->
</div>
el: '#app',
methods: {
// 冒泡 - 由内向外触发
// 捕获 - 由外向内触发
funcEvent(val) {
console.log(val)
}
}
.self 修饰符表示跳过冒泡事件和捕获事件,直接作用在该元素身上才可执行
.self 修饰符会监视事件是否直接作用在元素上,若不是则跳过该元素
<!-- .self修饰符当事件不直接作用在自身时,跳过冒泡与捕获事件 -->
<div class="father" @click.self="funcEvent('父元素-触发')">father
<div class="son" @click.self="funcEvent('子元素-触发')">son</div>
</div>
<!-- 点击子元素只触发子元素事件 可以阻止冒泡 -->
el: '#app',
methods: {
funcEvent(val) {
console.log(val)
}
}
.once 修饰符只执行一次事件
<!-- .once修饰符只执行一次 -->
<h3 @click.once="sayHi">Hello Vue</h3>
el: '#app',
methods: {
sayHi() {
console.log('Hi')
}
}
.passive 修饰符告诉浏览器你不想阻止事件的默认行为,对应 addEventListener 中的 passive 选项提供了 .passive 修饰符
.passive 修饰符常用于滚动监听与 @scroll 、@touchmove 中,在事件监听过程中,每次事件的触发,浏览器都会查询是否有 e.preventDefault() 阻止事件默认行为这会导致卡顿,添加 .passive 修饰符表示不用查询没有阻止默认行为,可以大大的提升滑动的流畅度
使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生
v-on:click.prevent.self会阻止默认行为所有点击,而v-on:click.self.prevent只会阻止对元素自身的点击不会阻止默认行为
<!-- .passive修饰符表示支持默认事件,默认事件不能被阻止 -->
<!-- 类似于addEventListener中的passive选项 -->
<button type="button" @click.passive="defaultEvent">支持默认事件</button>
<!-- 修饰符可以串联使用 .prevent.self会阻止默认行为所有点击-->
<div class="father" @click="funcEvent('father')">father
<a class="link" href="https://www.baidu.com" @click.prevent.self="funcEvent('link')">百度
<!-- 点击的时候会先.prevent阻止默认行为,然后判断是否是.self是则执行点击事件 -->
<div class="son" @click="funcEvent('son')">son</div>
</a>
</div>
<!-- 阻止对该元素自身的点击不会阻止默认行为 -->
<div class="father" @click="funcEvent('father')">father
<a class="link" href="https://www.baidu.com" @click.self.prevent="funcEvent('link')">百度
<!-- 会先判断self,不是self不会执行click事件,就不会执行阻止默认事件与指定事件 ,所以可以跳转 -->
<div class="son" @click="funcEvent('son')">son</div>
</a>
</div>
el: '#app',
methods: {
defaultEvent(e) {
// passive与prevent设置在一起prevent失效表示该元素不阻止默认事件
e.preventDefault();
console.log('支持默认事件')
},
funcEvent(val) {
console.log(val)
}
}
Vue 中可以使用以下三种键盘事件:
keydown —— 当一个按键被按下时会触发,如果按下一个键足够长的时间,它就会开始自动重复keyup —— 当按键被释放时会触发keypress —— 键盘按键按下抬起间隔期间触发在监听键盘事件时,我们经常需要检查详细的按键。Vue 允许为 v-on 在监听键盘事件时添加按键修饰符
keyCode已废弃: 该特性已经从 Web 标准中删除,虽然一些浏览器目前仍然支持它,但也许会在未来的某个时间停止支持,请尽量不要使用该特性
KeyboardEvent.key 暴露的任意有效按键名,大小写的按键名转换为 kebab-case 来作为修饰符KeyboardEvent.keyCode 获取按键码,该特性已被废除不推荐使用,可以使用 keyCode 按键码属性作为修饰符<input type="text" @keyup="keyEvent" v-model="title">
<!-- 将按键名作为按键修饰符 -->
<input type="text" @keyup.page-down="keyName" value="按PageDown触发">
<!-- 将按键码作为按键修饰符 -->
<input type="text" @keyup.68="keyCode" value="按D触发">
el: '#app',
data: function() {
return {
}
},
methods: {
keyEvent(e) {
// 1. 通过键盘事件对象key的属性获取按键名
// 2. 通过keyCode获取按键码 该属性已被废弃不建议使用
console.log('按键名 -' + e.key)
console.log('按键码 -' + e.keyCode)
},
keyName() {
console.log('按键名-触发')
},
keyCode() {
console.log('按键码-触发')
}
}
为了在必要的情况下支持旧浏览器,Vue 提供了绝大多数常用的按键码的别名:
.enter.tab.delete (捕获删除和退格键).esc.space.up.down.left.right<!-- 为了兼容旧的浏览器 vue提供了内置的按键码 -->
<input type="text" value="enter" @keyup.enter="keyEvent('enter')">
<input type="text" value="tab" @keyup.tab="keyEvent('tab')">
<input type="text" value="delete" @keyup.delete="keyEvent('delete')">
<input type="text" value="esc" @keyup.esc="keyEvent('esc')">
<input type="text" value="space" @keyup.space="keyEvent('space')">
<input type="text" value="up" @keyup.up="keyEvent('up')">
<input type="text" value="down" @keyup.down="keyEvent('down')">
<input type="text" value="left" @keyup.left="keyEvent('left')">
<input type="text" value="right" @keyup.right="keyEvent('right')">
el: '#app',
data: function() {
return {
}
},
methods: {
keyEvent(message) {
console.log(message)
}
}
可以通过全局 config.keyCodes 对象自定义按键修饰符别名
小驼峰形式不可用,应该使用 kebab-case 短横线且用双引号括起来
<input type="text" @keyup.outshift="keyEvent('shift')" value="shift">
<!-- 多字母别名用短横线形式 -->
<input type="text" @keyup.make-in-china="keyEvent('meta')" value="meta">
<!-- 数组形式,数组中的按键码都会触发回调 -->
<input type="text" @keyup.go="keyEvent('d或者right')" value="d按键或者right">
// 可以通过全局属性来自定义按键码别名
Vue.config.keyCodes = {
shifts: 16,
'make-in-china': 91,
go: [68, 39]
}
const vm = new Vue({
el: '#app',
data: function() {
return {
}
},
methods: {
keyEvent(val) {
console.log(val)
}
}
})
可以用如下修饰符来实现仅在按下相应按键时才触发鼠标或键盘事件的监听器
.ctrl.alt.shift.meta注意:在 Mac 系统键盘上,meta 对应 command 键 (⌘)。在 Windows 系统键盘 meta 对应 Windows 徽标键 (⊞)
修饰键与常规按键不同,在和 keyup 事件一起用时,事件触发时修饰键必须处于按下状态,只有在按住 ctrl 的情况下释放其它按键,才能触发 keyup.ctrl,而单单释放 ctrl 也不会触发事件。如果你想要这样的行为,请为 ctrl 换用 keyCode:keyup.17
修饰键在和 keydown 事件一起使用时正常触发事件
<!-- 系统修饰符ctrl alt shift meta -->
<!-- 在window上meta时windows按键 在Mac上是command按键 -->
<!-- 按住alt键再释放其它键才会触发-->
<input type="text" @keyup.alt.67="clearInput" v-model="value">
<!-- 修饰键配合keyup事件时,事件触发时修饰键必须处于按下状态 -->
<!-- 1. keyup 修饰键必须按下再释放其它键时触发 -->
<input type="text" @keyup.ctrl="keyChangeValue" v-model="message">
<!-- 2. keydown 修饰键按下正常触发事件 -->
<input type="text" @keydown.ctrl="keyChangeValue" v-model="info">
el: '#app',
data: function() {
return {
value: 'alt + c 清除内容',
message: 'keyup 按下修饰键再释放其它键',
info: 'keydown 修饰键按下正常触发事件'
}
},
methods: {
clearInput() {
this.value = ''
},
keyChangeValue(e) {
console.log(e.key);
}
}
.exact 修饰符允许你控制由精确的系统修饰符组合触发的事件,2.5.0版本新增
<!-- 即使 Alt 或 Shift 被一同按下时也会触发 -->
<button @click.ctrl="onClick">按下ctrl触发</button>
<!-- 有且只有 Ctrl 被按下的时候才触发 -->
<button v-on:click.ctrl.exact="onCtrlClick">只有ctrl按下触发</button>
<!-- 没有任何系统修饰符被按下的时候才触发 -->
<button v-on:click.exact="onClick">没有系统修饰符按下触发</button>
el: '#app',
data: function() {
return {
}
},
methods: {
onClick() {
console.log('onClick触发')
},
onCtrlClick() {
console.log('onCtrlClick触发')
}
}
在 Vue.js 2.2.0 中新增鼠标按钮修饰符,鼠标修饰符用来限制处理程序监听特定的鼠标按键
.left.right.middle这些修饰符会限制处理函数仅响应特定的鼠标按钮
<!-- 点击鼠标左键时触发 -->
<button @click.left='leftClick'>left</button>
<!-- 点击鼠标右键时触发 -->
<button @click.right='rightClick'>right</button>
<!-- 点击鼠标滚轮时触发 -->
<button @click.middle='middleClick'>middle</button>
el: '#app',
data: function() {
return {
}
},
methods: {
leftClick: function() {
alert('点击鼠标左键时触发')
},
rightClick: function() {
alert('点击鼠标右键时触发')
},
middleClick: function() {
alert('点击鼠标滚轮是触发')
}
}