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-click、item-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>
相关推荐
lovingsoft13 分钟前
Chrome Lighthouse 详解
前端·chrome
Qlly23 分钟前
全栈工程师怎么接需求?从一句「加个功能」聊到能开发、能验收
前端·后端
马可家的菠萝27 分钟前
你的微信“文件传输助手”,是不是已经成了第二个网盘?
前端·后端·架构
略略略啦27 分钟前
Vibe Coding 基于Spec DD和TDD的实践指南
前端
shmily麻瓜小菜鸡1 小时前
前端实现图片与PDF文字识别敏感信息打码方案
前端·pdf·状态模式
打工仔折腾 AI1 小时前
LangChain 工具调用实战:从 Tool 定义到 Agent 执行链路拆解
java·前端·人工智能·后端·python·langchain·ai agent 实战
汉堡大王95271 小时前
单次输出拉到100万Token:拆完 Gemini 4 Argon 的续写协议,才看懂谷歌这7个月在憋什么
前端·人工智能·后端
看浪的路人1 小时前
第9讲:大模型应用监控与可观测性——OpenTelemetry + Prometheus + Grafana 全链路追踪
java·前端·spring
内存过载1 小时前
用表格模拟甘特图:项目排期的土办法
前端·低代码
葡萄城技术团队1 小时前
用 SpreadJS 数据验证实现省市区三级联动
前端