关于事件的基本概念
对事件的捕获
在添加响应代码的时候,可以使用两种方式将事件响应代码和事件绑定:
- v-on:事件名,比如:v-on:click
- @事件名:比如:**@click**,推荐这种方式
事件响应代码
在注册事件时直接写代码
第一种方式是在v-on:click/@click中直接写简单代码:
<button v-on:click="score++">涨分</button>
<button @click="score--">降分</button>
调用外部的代码
首先需要定义对应的方法changeName:
const app = Vue.createApp({
data() {
return {
id: '9901',
name: 'Lucas',
score: '80'
}
},
methods: {
changeName() {
this.name = 'Jessie'
}
}
})
app.mount('#app')
然后在HTML中进行调用:
<span @click="changeName">换名</span>
事件中参数的传递
默认参数
首先,如果在调用事件处理函数时不传递任何参数的话,则事件处理函数会收到一个包含事件本身的对象。
比如:调用时:
<div @mouseleave="handleEvent">
则会在handleEvent中收到一个event对象:
handleEvent(e) {
console.log(e.type);
}
其中的e.type对应的就是各种事件的名称,比如:mouseover, mouseleave等。
自定义参数
也可以在注册事件处理函数时,传递给它一个自定义参数:
<div @mouseover="handleEvent($event, 100)">
这样,在事件处理函数中就会收到两个参数:
- 第一个参数$event为事件对象本身。这里只有$event是关键字,它在参数列表中的位置并没有关系。
- 第二个参数为自定义参数
handleEvent(e, param) {
console.log(e.type);
if(param) {
console.log(param);
}
},
如果想要在同一事件中触发两个事件处理函数:
<button @click="changeName, notify">Change</button>
事件修饰符event modifier
有些时候我们需要捕获特殊的事件,比如:当按下Ctrl / Alt / Shift的时候单击鼠标。这时就可以非常方便的时候事件修饰符了:
<button @click.ctrl="showModal = true">Ctrl + Click to Show ModalBox</button>
事件修饰符还能实现这样的操作,只有当用户单击当前组件,而不是其子组件的时候,才能响应单击事件:
<div class="background" @click.self="closeModal">
鼠标事件
- @mouseover
- @mouseleave
- @dblclick
- @mousemove
在创建不同事件处理函数时,可能需要使用事件对象的不同属性。比如:对于鼠标移动事件mousemove:
console.log('当前坐标', e.offsetX, e.offsetY);
自定义事件
设想一个需求,我们需要一个按钮,单击后打开模式对话框,之后单击屏幕关闭这个对话框。
打开模式对话框
要想打开模式对话框,我们可以在父组件,比如App.vue中设定一个属性,然后根据这个属性值来决定是否显示模式对话框:
<div v-if="showModal">
<ModalBox />
</div>
后面可以通过在按钮单击事件中更改这个属性值来控制显示/隐藏模式对话框:
<button @click="showModal = true">Show ModalBox</button>
对应的JS:
data() {
return {
showModal: false,
};
},
关闭模式对话框
由于我们通过父组件中的showModal属性来控制显示/关闭模式对话框,因此要实现关闭对话框时,我们需要更改父组件的这个属性。那么更改该父组件属性的方法必然是需要定义在负组件中。比如:
methods: {
toggleModal() {
this.showModal = !this.showModal;
},
},
现在有两种不同的实现方式来通过子组件更新父组件属性值:
- 传递更改父组件属性值的函数toggleModal到子组件
- 在父组件定义自定义事件,然后在子组件触发这个事件
下面分别介绍一下。
传递toggleModal函数到子组件
在调用子组件的时候:
<ModalBox
header="ModalBox header"
text="ModalBox text"
theme="light"
closeFunction="toggleModal"/>
然后在子组件中首先接收到这个作为参数的函数:
props: ["header", "text", "theme", "closeFunction"],
然后在模式对话框对应的HTML父元素上调用这个方法:
<div class="background" @click="closeFunction">
使用自定义事件
可以在父组件中定义一个自定义事件,比如叫做close,然后当这个事件被触发时,调用更改属性的方法toggleModal:
<ModalBox
header="ModalBox header"
text="ModalBox text"
theme="light"
@close="toggleModal"
/>
那么,该在什么地方来触发这个事件呢?这取决于我们要实现的逻辑,比如:在这个例子中,模式对话框的HTML父元素位整个页面,那么当单击这个HTML父元素的时候,需要关闭对话框。因此,这就需要在该HTML元素被单击时来触发这个事件:
在子组件中:
methods: {
closeModal() {
this.$emit("close");
},
},
对应的HTML:
<div class="background" @click="closeModal">
<div class="modal" ...>
...
</div>
</div>