Vue 3教程 - 事件处理


关于事件的基本概念

对事件的捕获

在添加响应代码的时候,可以使用两种方式将事件响应代码和事件绑定:

  • 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>  

文章作者: 逻思
版权声明: 本博客所有文章除特別声明外,均采用 CC BY-NC-ND 4.0 许可协议。转载请注明来源 逻思 !
  目录