开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第3天,点击查看活动详情
事件不管是在原生还是vue中都是经常会用到的,所以了解事件就是一件非常有必要的事情,我们这篇文章主要是围绕vue来介绍一下事件是如何使用的,以及我们常用的一些事件机制。
事件处理
1. 监听
在vue中事件监听是通过v-on指令去监听的,并在触发的时候运行一些JavaScript代码。即v-on:后面加事件类型
<span class="btn" v-on:click="clearFun">点我触发点击事件</span>
v-on指令也可以简写成@符
<span class="btn" @click="clearFun">点我触发点击事件</span>
2. 事件处理方法
2.1 基础用法
在使用事件处理的时候我们需要使用v-on去监听事件,我们可以直接将事件的内容写在v-on指令后面,比如下面这种:
<span class="btn" v-on:click="num++">{{num}}</span>
对于比较复杂的事件内容,我们通常会写一个方法,将逻辑写在方法里面,然后将方法名绑定在v-on指令上。
<button @click="sayHello">sayHello</button>
methods: {
sayHello () {
alert('hello world!')
}
}
2.2 传参用法
上面介绍的都是一些很基础的用法,但是在实际开发中,我们通常需要传参,下面介绍一下传参的用法。不传参的时候,我们可以直接在v-on后面绑定方法名,但是如果需要传参的话我们需要使用括号,里面传参
<button @click="showMsg('hello')">showMsg</button>
methods: {
showMsg (msg) {
alert(msg)
}
}
这样我们传什么参数就会弹出什么信息
2.3 事件对象用法
在事件中我们有一个很重要的事件对象event,只要有了事件就一定会存在事件对象,事件对象是系统自动创建的,里面包含了很多属性。 在Vue中需要在v-on绑定的方法中传一个$event,这样就能拿到事件对象了
<button @click="showMsg($event)">showMsg</button>
methods: {
showMsg (e) {
console.log(e)
}
}
需要注意的是如果想要使用事件对象,必须传入$event,否则会报错。
从打印信息可以看出,事件对象里面包含很多信息,我们常用的就是以下几个属性,重点关注一下就行。
1). type属性
事件类型
2). target和currentTarget
target是触发事件的对象,currentTarget是绑定事件的对象
3). keyCode
被按下键盘的键码(ASCII码),这个只有在键盘事件中才会有对应的属性
4). ctrlKey, altKey, shiftKey
这几个属性值也都是在键盘事件中才会有对应的属性。ctrlKey返回是否按下了ctrl键,altKey返回是否按下了alt键,shiftKey返回是否按下了shift键
5). screenX与screenY
screenX是鼠标点击的坐标距电脑屏幕水平方向的距离,screenY鼠标点击的坐标距离电脑屏幕垂直方向的距离
6). offsetX与offsetY
offsetX鼠标点击的坐标距自身水平方向元素的距离,不受滚动条影响。offsetY鼠标点击的坐标距自身垂直方向元素的距离
7). clientX与clientY
clientX是鼠标点击的坐标距窗口可视区水平方向元素的距离,clientY是鼠标点击的坐标距窗口可视区垂直方向元素的距离
2.4 事件类型
对于我们开发vue项目来说,常见的事件方法主要有下面这几种js原生事件和自定义事件
2.4.1 鼠标点击事件 点击事件是在开发中用的最多的事件,有单击是双击事件两种
- click: 单机事件
- dbclick:双击事件
2.4.2 焦点事件 焦点事件有两种,失去焦点和获得焦点,这种事件一般用于input输入框中
- focus: 元素获得焦点(不会冒泡)
- blur: 元素失去焦点(不会冒泡)
2.4.3 鼠标其他事件 除了上面介绍的鼠标点击事件外,鼠标还具有其他的一些事件。
- mousedown: 在元素上按下任意鼠标按钮
- mouseup: 在元素上释放任意鼠标按键
- mouseenter: 指针移到有事件监听的元素内
- mouseleave: 指针移出元素范围内(不会冒泡)
- mousemove: 指针在元素内移动时持续触发
- mouseover: 指针移到有事件监听的元素或者它的子元素内
- moseout: 指针移出元素,或者移到它的子元素上
- select: 有文本被选中
- wheel: 滚轮向任意方向移动
2.4.4 表单事件 表单事件一般是用在form元素上的,常见的有两种元素
- reset: 点击重置按钮时触发
- submit:点击提交按钮时
2.4.5 $emit自定义事件 除了上面这些原生的js事件外,vue还可自定义事件,这种情况一般用于父子组件之间传值时:
子组件child.vue
goToParent() {
this.$emit('childToParent')
}
父组件parent.vue
<child @childToParent="getChildData" />
getChildData() {
// 这里可以拿到子组件给父组件传递的值
}
3. 修饰符
在vue中,修饰符分为以下五种:
- 表单修饰符
- 事件修饰符
- 鼠标按键修饰符
- 键值修饰符
- v-bind修饰符
3.1 表单修饰符
3.1.1 lazy
在表单元素中,只有当光标离开标签的时候,才会将值赋给value。
<input type="text" v-model.lazy="msg" >
3.1.2 trim
这个修饰符会自动过滤输入的首空格和尾空格,中间的不会过滤
<input type="text" v-model.trim="msg" >
3.1.3 number
这个修饰符能将输入的内容自动转成number类型。
<input type="text" v-model.number="msg" >
3.2 事件修饰符
在js事件机制中,我们知道事件分为捕获阶段和冒泡阶段。
捕获阶段就是从根元素往下找到目标元素的过程。
冒泡阶段就是从目标元素往上到根元素的过程。
为了避免事件冒泡,默认行为等,vue增加了一些事件修饰符
3.2.1 stop
这个修饰符阻止了事件冒泡,相当于原生事件的event.stopPropagation方法
下面这个例子是存在事件冒泡的事件
<template>
<div class="test-wrapper">
<div class="box1" @click="click1">
<div class="box2" @click="click2">
<div class="box3" @click="click3"></div>
</div>
</div>
</div>
</template>
<script>
export default {
data () {
return {
}
},
methods: {
click1 () {
console.log('!!!box1 click')
},
click2 () {
console.log('!!!box2 click')
},
click3 () {
console.log('!!!box3 click')
}
}
}
</script>
<style lang="scss" scoped>
.test-wrapper {
.box1 {
width: 300px;
height: 300px;
border: 1px solid #999;
.box2 {
width: 200px;
height: 200px;
border: 1px solid #999;
.box3 {
width: 100px;
height: 100px;
border: 1px solid #999;
}
}
}
}
</style>
使用.stop
<div class="box1" @click="click1">
<div class="box2" @click="click2">
<div class="box3" @click.stop="click3"></div>
</div>
</div>
3.2.2 prevent
这个修饰符会阻止元素默认行为。比如下面的a标签的点击事件会触发跳转
<a href="https://juejin.cn/" @click="console.log('触发事件了')">点我跳转</a>
效果: 打印完休息后,页面会跳转到掘金首页
使用.pevent之后就不会跳转
<a href="https://juejin.cn/" @click.prevent="console.log('触发事件了')">点我跳转</a>
3.2.3 self
这个修饰符是只有当event.target是当前元素自身时触发处理函数
<div class="box1" @click="click1">
<div class="box2" @click="click2">
<div class="box3" @click.self="click3"></div>
</div>
</div>
3.2.4 once
这个修饰符说明事件只能触发一次,后面的都不会触发
<div class="box3" @click.once="click3"></div>
3.2.5 capture
前面介绍的这几种修饰符是比较常见的,下面介绍的几种修饰符用的相对来说没有那么多 一般事件的触发都是在冒泡阶段来触发的,像上面那个例子一样,如果想要事件触发从包含这个元素的顶层开始往下触发
<div class="box1" @click="click1">
<div class="box2" @click.capture="click2">
<div class="box3" @click="click3"></div>
</div>
</div>
3.2.6 passive
当我们需要监听元素滚动的时候,会一直触发onscroll事件,导致页面卡顿,这时就可以使用这个修饰符来避免这种卡顿
<div class="box3" @scroll="onScroll"></div>
3.2.7 native
这个修饰符能让组件像html内置标签那样监听组件根元素的原生事件,否则需要借助自定义事件来完成。不过需要注意的是这个native修饰符只能用来修饰组件元素
<child class="box3" @click.native="myClick"></child>
3.3 鼠标按键修饰符
3.3.1 left
这个修饰符表示按了鼠标左键才会触发
<div class="box3" @click.left="consoleMsg('left')"></div>
3.3.2 right
这个修饰符表示按了鼠标左键才会触发
<div class="box3" @click.right="consoleMsg('right')"></div>
3.3.3 middle
这个修饰符表示按了鼠标左键才会触发
<div class="box3" @click.middle="consoleMsg('middle')"></div>
3.4 键盘修饰符
键盘修饰符是用来修饰键盘事件的,只有按键为keyCode的时候才会触发,其中keyCode可以为以下两种类型的值
- 普通键值:enter, tab, delete, space, esc, up等
- 系统修饰键:ctrl, alt, meta, shift
<div class="box3" @keyup.keyCode="consoleMsg('ok')"></div>
3.5 v-bind修饰符
这类修饰符主要是为属性进行操作,通常有三种:
- async
- prop
- camel
3.5.1 async
这个修饰符能对props进行一个双向绑定
// 父组件
<parent :message="msg" @update:myMessage='update'></parent>
update(e) {
this.msg = e
}
// 子组件
send() {
this.$emit('update:myMessage', params);
}
可以使用async
// 父组件
<child :message.async="bar"></child>
// 子组件
this.$emit('update:myMessage', params);
3.5.2 prop
这个修饰符设置自定义标签属性,避免暴露数据
<input :type="text" v-model="msg" :index.prop="index"/>
3.5.3 camel
这个修饰符可以将变量命名为驼峰命名法
<input :type.camel="text" v-model="msg" />