组件的自定义事件是一种组件间的通信方式,它适用于子组件向父组件传递数据或行为。vue也有内置一些常用系统事件,例如:鼠标点击,表单提交、滚动事件等等。
组件常用事件
在 Vue 中,常用的事件有以下几种:
- @click:响应鼠标点击事件;
- @mouseover:响应鼠标移动到元素上方事件;
- @keydown:响应键盘按下事件;
- @submit:响应表单提交事件;
- @focus:响应元素获得焦点事件;
- @blur:响应元素失去焦点事件;
- @change:响应输入框内容变化事件;
- @scroll:响应元素滚动事件。
使用方法:
- 绑定事件:使用 @ 符号加事件名称,例如 @click;
- 在 Vue 实例中定义处理事件的方法,例如 onClick;
- 在实例中使用 methods 属性,将方法绑定到事件上。
自定义事件
除了以上常用事件,但是大多时候需要我们自己根据业务需要来自定义事件。例如在一个抽屉公共子组件中我们点击了提交@click="submit"
按钮,然后在父组件中我们需要针对点击提交后进行业务逻辑处理@submit="handleSubmit"
。
$emit()
在组件的模板表达式中,可以直接使用 $emit
方法触发自定义事件,例如在子组件child.vue
中定义如下
1 2 3 4 5 6
| <template> <div> <button @click="$emit('emitClick')">$emit触发Click事件</button><br> </div> </template>
|
在父组件中进行引用
1 2 3 4 5 6 7 8 9 10 11
| <template> <div> <child @emitClick="emitClick"></child> </div> </template>
<script setup> import child from '~/components/Child.vue' const emitClick = () => { alert('emit方式触发了此事件') }
</script>
|
defineEmits()
组件可以显式地通过 defineEmits()
宏来声明它要触发的事件,但是我们在 <template>
中使用的 $emit
方法不能在组件的 <script setup>
部分中使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <template> <div> <button @click="$emit('emitClick')">$emit触发Click事件</button><br> <input type="checkbox" @change="handChange"> </div> </template>
<script setup> const emits = defineEmits(['parentChange']) const handChange = () => { emits('parentChange') } </script>
|
在父组件中同样可以调用自定义事件。
1 2 3 4 5 6 7 8 9 10 11 12
| <template> <div> <child @parentChange="parentChange" @emitClick="emitClick"></child> </div> </template>
<script setup> import child from '~/components/Child.vue' const parentChange = () => { alert('子组件触发了此事件') } const emitClick = () => { alert('emit方式触发了此事件') }
</script>
|
事件参数
有时候我们会需要在触发事件时附带一个特定的值。比如传递一个用户名、头像参数等等。
如下所示我们可以直接在$emit
中传递参数,也可以在emits()
方法中传递,参数可以是多个。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <template> <div> <button @click="handleAdd">点击触发Click事件带参数</button><br> <button @click="$emit('emitClick',2)">$emit触发Click事件</button><br> <input type="checkbox" @change="handChange"> </div> </template>
<script setup> const emits = defineEmits(['addNum','parentChange']) const handleAdd = () => { emits('addNum',1) } const handChange = () => { emits('parentChange') } </script>
|
父组件可以直接接收子组件传递过来的参数。
1 2 3 4 5 6 7 8 9 10 11 12 13
| <template> <div> <child @addNum="handleIncreate" @parentChange="parentChange" @emitClick="emitClick"></child> </div> </template>
<script setup> import child from '~/components/Child.vue' const handleIncreate = (data) => { alert('子组件触发了此事件,传递的值是' + data) } const parentChange = () => { alert('子组件触发了此事件') } const emitClick = (data) => { alert('emit方式触发了此事件'+data) }
</script>
|
参考资料