8、事件修饰符

8、事件修饰符

目标:

1、掌握四个事件修饰符,它们分别是 stop / prevent / self / once
2、搞清楚 stop修饰符 与 self修饰符 之间的区别

一、stop

作用:阻止事件冒泡。

<style>
    .box {
      width: 100px;
      height: 100px;
      border: 1px solid red;
  </style>
<div id="app">
    <div @click="boxClick" class="box">    // 1、div 父元素
      <button @click="btnClick">click me</button>    // 2、button 子元素
var app = new Vue({
  el: '#app',
  data: {
  methods: {
    boxClick() {    // 3、父元素的单击事件
      console.log('box click')
    btnClick() {    // 4、子元素的单击事件
      console.log('btn click')
})

上面代码中,定义了 div 父元素 和 button 子元素,并分别给他们添加了单击事件。

  • 当点击 div 时(不点击 button ),控制台会打印出 "box click" ;
  • 当点击 button 时,控制台会打印出 "btn click" 和 "button click" 。

这是因为,button 作为 div 的子元素,当点击 子元素button 时,button 的单击事件会冒泡到 父元素div ,从而触发 div 的 click 事件。所以会先执行 button 的 click 事件,再执行 div 的 click 事件。

然而很多时候,我们是不希望事件会往上冒泡的。比如上面的例子,我们只希望 button 的 click 事件被触发,不希望 div 的 click 事件被触发。

针对这个问题,Vue 中的 stop 修饰符就派上了用场,它会阻止事件的冒泡。

你只需要在 button 的 click 事件后面加上 ".stop",如:

<button @click.stop="btnClick">click me</button>

注意:修饰符以 点 开头。

这样一来,button 的 click 事件就不会向上冒泡,div 的 click 事件也就不会被触发。


二、prevent

作用:提交事件,并且不重载页面。

<div id="app">
    <form action="" @submit="handle">    // 1、一个表单,并且定义了 submit 事件
      <button type="submit">提交</button>    // 2、当点击按钮时,表单就会被提交
    </form>
var app = new Vue({
  el: '#app',
  data: {
  methods: {
    handle() {
      console.log('表单被提交了')    // 3、表单提交后,打印文本
})

上面代码中,当点击表单中的提交按钮后,表单就会被提交,控制台会打印文本,并且页面会被刷新。需要注意的是, submit 事件应该定义在 form 元素上,而不是 button 元素上。

然而页面被刷新这件事,明显不利于用户体验,所以很多时候,会有提交表单时阻止页面刷新的需求。

在 Vue 中,要做到这件事很简单,只需要用到 prevent 修饰符即可:

<form action="" @submit.prevent="handle">    // 在 submit 事件后加上 .prevent
    <button type="submit">提交</button>
</form>

此时,表单仍然会被提交,控制台仍然会打印文本,但是页面不再刷新。


三、self

作用:只有当前元素自身才能触发,当前元素的子元素不能触发。

以上面事件冒泡的代码为例:

<style>
    .box {
      width: 100px;
      height: 100px;
      border: 1px solid red;
  </style>
<div id="app">
    <div @click="boxClick" class="box">    // 1、div 父元素
      <button @click="btnClick">click me</button>    // 2、button 子元素
var app = new Vue({
  el: '#app',
  data: {
  methods: {
    boxClick() {    // 3、父元素的单击事件
      console.log('box click')
    btnClick() {    // 4、子元素的单击事件
      console.log('btn click')
})

上面代码中,定义了 div 父元素 和 button 子元素,并分别给他们添加了单击事件。

  • 当点击 div 时(不点击 button ),控制台会打印出 "box click" ;
  • 当点击 button 时,控制台会打印出 "btn click" 和 "button click" 。

原因不再赘述。

这里需要注意的是,父元素div 的 click 事件,并不是只有 div 自己能触发,div 的子元素 button 也可以通过冒泡触发 div 的 click 事件。

而我们不希望 button 触发 div 的 click 事件,只希望 div 自己触发自己的 click 事件。

解决办法:

如上面说到的,你可以给 子元素button 加 stop 修饰符,阻止 button 的 click 事件向上冒泡,实现不触发 父元素div 的 click 事件的目的。

但是我们都知道,父元素div 可能会有很多个子元素,如果其他子元素也有 click 事件,那么就要给所有子元素加上 stop 修饰符,这未免有点麻烦。

所以,我们希望,所有子元素都不要触发父元素的 click 事件,只让父元素自己触发自己的 click 事件。(猴子猴孙快闪开,让俺老孙来对付他们,dai,妖怪,哪里跑~~)

所以我们只需要给父元素加上 self 修饰符即可,如:

<div @click.self="boxClick" class="box">
    <button @click="btnClick">click me</button>
</div>

此时,点击 div 元素(不点击 button),会触发 click 事件,点击 button ,不会触发父元素的 click 事件。

ps:其实我用的也不多,不敢说了解。但是我还是发表一下我的愚见,供同学们参考。

self 修饰符 与 stop 修饰符 可能会让你有点混淆不清,你需要再细细品味它们之间的区别:

  • stop 是写在子元素上的,而 self 是写在父元素上的;
  • stop 是为了阻止子元素的事件向父元素冒泡,self 是为了不让子元素触发我(父元素)的事件。

四、once

作用:让事件只触发一次。

<div id="app">
    <button @click.once="once">once</button>  // 1、这个 button 只能点一次
    <button @click="more">more</button>       // 2、这个 button 可以点多次
var app = new Vue({
  el: '#app',
  data: {
  methods: {
    once() {
      console.log('只执行一次')