vue-06(“$emit”和事件修饰符)

了解"$emit"和事件修饰符

$emit 和 Event Modifier 是构建交互式和动态 Vue.js 应用程序的基本工具。它们使组件能够有效地通信并精确处理用户交互。了解这些概念对于创建可重用、可维护和可扩展的 Vue.js 组件至关重要。本课将深入探讨用于自定义事件创建和处理的 $emit 的复杂性,并探索事件修饰符在 Vue.js 应用程序中简化事件处理的强大功能。

了解 $emit

$emit 方法是 Vue 的组件触发自定义事件的机制。然后,父组件可以监听此事件,从而允许在组件树中向上通信。它是基于组件的架构的基石,使组件能够在与周围环境交互的同时保持独立性。

$emit 的基本用法

最简单的 $emit 形式涉及使用要触发的事件的名称调用方法。例如,如果组件内有一个按钮,并且希望在单击该按钮时通知父级,则可以执行以下作:

html 复制代码
<template>
  <button @click="handleClick">Click me</button>
</template>

<script>
export default {
  methods: {
    handleClick() {
      this.$emit('custom-click');
    }
  }
}
</script>

在此示例中,单击按钮时,将执行 handleClick 方法,该方法反过来会发出名为 custom-click 的自定义事件。然后,父组件可以使用 v-on(或其简写 @)来监听这个事件。

html 复制代码
<template>
  <MyComponent @custom-click="handleCustomClick" />
</template>

<script>
import MyComponent from './MyComponent.vue';

export default {
  components: {
    MyComponent
  },
  methods: {
    handleCustomClick() {
      console.log('Custom click event received!');
    }
  }
}
</script>

使用 $emit 传递数据

通常,您需要将数据与事件一起发送。这可以通过在事件名称后向 $emit 传递其他参数来轻松实现。这些参数将可用于父组件中的事件处理程序。

html 复制代码
<template>
  <button @click="handleClick">Click me</button>
</template>

<script>
export default {
  data() {
    return {
      message: 'Hello from child!'
    };
  },
  methods: {
    handleClick() {
      this.$emit('custom-click', this.message);
    }
  }
}
</script>

现在,父组件可以在处理事件时访问message

html 复制代码
<template>
  <MyComponent @custom-click="handleCustomClick" />
</template>

<script>
import MyComponent from './MyComponent.vue';

export default {
  components: {
    MyComponent
  },
  methods: {
    handleCustomClick(message) {
      console.log('Received message:', message); // Output: Received message: Hello from child!
    }
  }
}
</script>

事件名称和约定

虽然从技术上讲,你可以使用任何字符串作为事件名称,但最佳做法是使用 kebab-case(例如,custom-clickitem-selected)。此约定可确保一致性,并避免在不同环境中出现区分大小写的潜在问题。它还提高了可读性。

示例:从表单组件发出数据

考虑一个允许用户输入其姓名和电子邮件的表单组件。提交表单后,组件应发出包含表单数据的事件。

html 复制代码
<template>
  <form @submit.prevent="handleSubmit">
    <label for="name">Name:</label>
    <input type="text" id="name" v-model="name">
    <label for="email">Email:</label>
    <input type="email" id="email" v-model="email">
    <button type="submit">Submit</button>
  </form>
</template>

<script>
export default {
  data() {
    return {
      name: '',
      email: ''
    };
  },
  methods: {
    handleSubmit() {
      this.$emit('form-submitted', {
        name: this.name,
        email: this.email
      });
    }
  }
}
</script>

然后,父组件可以侦听表单提交的事件并访问表单数据:

html 复制代码
<template>
  <MyForm @form-submitted="handleFormSubmitted" />
</template>

<script>
import MyForm from './MyForm.vue';

export default {
  components: {
    MyForm
  },
  methods: {
    handleFormSubmitted(formData) {
      console.log('Form data received:', formData);
      // { name: 'John Doe', email: 'john.doe@example.com' }
    }
  }
}
</script>

事件修饰符

事件修饰符是用点 (.) 表示的特殊后缀,您可以将其添加到 v-on 指令中以修改事件侦听器的默认行为。它们提供了一种简洁的方法,可以直接在模板中处理与事件相关的常见任务,而无需在组件的方法中编写额外的代码。

.stop

.stop 修饰符调用 event.stopPropagation(), 防止事件在 DOM 树中冒泡。当您想要阻止事件触发父元素上的处理程序时,这很有用。

html 复制代码
<template>
  <div @click="handleOuterClick">
    Outer
    <button @click.stop="handleInnerClick">Inner</button>
  </div>
</template>

<script>
export default {
  methods: {
    handleOuterClick() {
      console.log('Outer click');
    },
    handleInnerClick() {
      console.log('Inner click');
    }
  }
}
</script>

在此示例中,单击 "Inner" 按钮将仅触发 handleInnerClick.stop 修饰符可防止 click 事件上升到 div,因此不会调用 handleOuterClick

.prevent

.prevent 修饰符调用 event.preventDefault(), 从而阻止事件的默认作。这通常与表单提交一起使用,以防止页面重新加载。

html 复制代码
<template>
  <form @submit.prevent="handleSubmit">
    <button type="submit">Submit</button>
  </form>
</template>

<script>
export default {
  methods: {
    handleSubmit() {
      console.log('Form submitted');
    }
  }
}
</script>

在这种情况下,单击"提交"按钮将触发 handleSubmit,但由于 .prevent 修饰符,表单实际上不会提交和重新加载页面。

.capture

.capture 修饰符在 capture 模式下添加事件侦听器。这意味着事件侦听器将在附加到捕获元素内的元素的任何事件侦听器之前触发。

html 复制代码
<template>
  <div @click.capture="handleOuterClick">
    Outer
    <button @click="handleInnerClick">Inner</button>
  </div>
</template>

<script>
export default {
  methods: {
    handleOuterClick() {
      console.log('Outer click (capture)');
    },
    handleInnerClick() {
      console.log('Inner click');
    }
  }
}
</script>

当您单击"Inner"按钮时,将首先触发 handleOuterClick(在捕获阶段),然后是 handleInnerClick(在冒泡阶段)。

.self

仅当事件是从元素本身而不是从子元素调度时,.self 修饰符才会触发处理程序。

html 复制代码
<template>
  <div @click.self="handleOuterClick">
    Outer
    <button @click="handleInnerClick">Inner</button>
  </div>
</template>

<script>
export default {
  methods: {
    handleOuterClick() {
      console.log('Outer click (self)');
    },
    handleInnerClick() {
      console.log('Inner click');
    }
  }
}
</script>

直接单击 div 将触发 handleOuterClick。但是,单击 "Inner" 按钮只会触发 handleInnerClick,因为该事件源自按钮,而不是 div 本身。

.once

.once 修饰符确保事件侦听器仅触发一次。在第一次触发后,侦听器会自动删除。

html 复制代码
<template>
  <button @click.once="handleClick">Click me</button>
</template>

<script>
export default {
  methods: {
    handleClick() {
      console.log('Clicked once');
    }
  }
}
</script>

在此示例中,handleClick 将仅在第一次单击按钮时执行。后续点击将不起作用。

.passive

.passive 修饰符通过指示事件侦听器不会调用 preventDefault() 来提高性能,尤其是在移动设备上。这允许浏览器优化滚动性能。

html 复制代码
<template>
  <div @scroll.passive="handleScroll">
    Scrollable content...
  </div>
</template>

<script>
export default {
  methods: {
    handleScroll() {
      console.log('Scrolling');
    }
  }
}
</script>

使用 .passive 会告诉浏览器 handleScroll 不会阻止默认滚动行为,从而允许更流畅的滚动。

键修饰符:.enter.tab.delete.esc.space.up.down.left.right

Vue 还提供了监听特定键盘事件的 key modifier。这些修饰符对于处理表单和其他交互式元素中的键盘输入特别有用。

html 复制代码
<template>
  <input @keyup.enter="handleEnter">
</template>

<script>
export default {
  methods: {
    handleEnter() {
      console.log('Enter key pressed');
    }
  }
}
</script>

在此示例中,只有在聚焦输入字段时按下 Enter 键时,才会调用 handleEnter

您还可以使用特定的键代码:

html 复制代码
<template>
  <input @keyup.13="handleEnter">
</template>

<script>
export default {
  methods: {
    handleEnter() {
      console.log('Enter key pressed');
    }
  }
</script>

系统修饰键:.ctrl.alt.shift.meta

仅当同时按下相应的修饰键时,这些修饰符才会触发侦听器。例如,@click.ctrl="doSomething" 只有在单击时按住 Ctrl 键时才会触发 doSomething

鼠标按钮修饰符:.left.right.middle

这些修饰符将侦听器限制为仅在按下相应的鼠标按钮时触发。

链接修饰符

可以将多个修改器链接在一起以组合其效果。例如,@click.stop.prevent 将停止事件传播并阻止默认作。

考虑一个模态组件,当用户点击模态内容外部或按下 Escape 键时,该组件应关闭。

html 复制代码
<template>
  <div class="modal-overlay" @click.self="closeModal">
    <div class="modal-content">
      <slot></slot>
      <button @click="closeModal">Close</button>
    </div>
  </div>
</template>

<script>
export default {
  methods: {
    closeModal() {
      this.$emit('close');
    }
  },
  mounted() {
    document.addEventListener('keyup', this.handleEsc);
  },
  beforeUnmount() {
    document.removeEventListener('keyup', this.handleEsc);
  },
  methods: {
    handleEsc(event) {
      if (event.key === 'Escape') {
        this.closeModal();
      }
    }
  }
}
</script>

在父组件中:

html 复制代码
<template>
  <button @click="showModal = true">Open Modal</button>
  <MyModal v-if="showModal" @close="showModal = false">
    Modal Content
  </MyModal>
</template>

<script>
import MyModal from './MyModal.vue';

export default {
  components: {
    MyModal
  },
  data() {
    return {
      showModal: false
    };
  }
}
</script>
相关推荐
崔庆才丨静觅11 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby606112 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了12 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅12 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅13 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅13 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment13 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅13 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊13 小时前
jwt介绍
前端
爱敲代码的小鱼14 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax