一、什么是自定义事件?
- 自定义事件是 Vue 组件间通信的一种机制。
- 子组件通过
this.$emit('事件名', 数据)
触发一个事件。 - 父组件监听这个事件并执行相应的逻辑。
二、基本使用
准备工作
demo 继续使用笔记8中的 链接为demo
在views文件夹下 创建新的文件夹为customevent
在customevent文件夹下
创建文件Parent.vue
<template><div class="props-text"><h1>custom event 自定义事件</h1><h1>我是父组件</h1></div>
</template>
<script setup></script><style scoped>
.props-text {
width: 400px;
height: 400px;
background-color: burlywood;
}
</style>
添加路由
import {createRouter , createWebHistory} from 'vue-router'
const routes = [{path: '/',name: 'index',component: () => import('@/views/index.vue')},{path: '/props',name: 'props',component: () => import('@/views/props/Parent.vue')},{path: '/customevent',name: 'customevent',component: () => import('@/views/customevent/Parent.vue')},]const router = createRouter({history: createWebHistory(),routes
})
export default router
在APP.vue 中 添加导航
<script setup></script><template>
<div class="com"><h1>各种Vue组件间通信/传值</h1><div><h2 style="display: inline">演示:</h2> <router-link to="/">index</router-link> <router-link to="/props">props</router-link> <router-link to="/customevent">custom event</router-link> </div><br><router-view></router-view></div>
</template><style scoped>.com {margin: 10px;}</style>
<style>.box {border: solid 1px #aaa;margin: 5px;padding: 5px;}
</style>
当父组件想给 子组件绑定一个原生dom事件时
创建子组件1
在customevent文件夹下
创建文件Child1.vue
<template><div><div class="child1"><div class="child1-title">Child1</div></div></div>
</template>
<script setup></script>
<style scoped>.child1{background-color: red;height: 100px;width: 100px;}.child1-title{color: white;}</style>
在父组件中 引用子组件1
<template><div class="props-text"><h1>custom event 自定义事件</h1><h1>我是父组件</h1><hr><!--vue2框架当中:这种写法自定义事件,可以通过.native修饰符变为原生DOM事件vue3框架下面写法其实即为原生DOM事件vue3:原生的DOM事件不管是放在标签身上、组件标签身上都是原生DOM事件 --><Child1 @click="handler2(1,2,$event)"></Child1></div>
</template>
<script setup>
import Child1 from './Child1.vue'const handler1 = () => {console.log('父组件点击了')
}const handler2 = (a,b,$event) => {console.log(a,b,$event)
}
</script><style scoped>
.props-text {
width: 400px;
height: 400px;
background-color: burlywood;
}
</style>
效果展示:
此时handler2自定义事件 点击子组件任意地方 都可触发
例如 在子组件1中 添加一个按钮
子组件代码
<template><div><div class="child1"><div class="child1-title">Child1</div><button>点我也触发</button></div></div>
</template>
<script setup></script>
<style scoped>.child1{background-color: red;height: 100px;width: 100px;}.child1-title{color: white;}</style>
点击按钮时 控制台输入的结果是一样的
当子组件想给父组件传递信息时 使用自定义事件
创建子组件2
<template><div><div class="Child2"><div class="Child2-title">Child2</div><button @click="handler">点击我触发方法xxx</button></div></div>
</template>
<script setup>
//利用defineEmits方法返回函数触发自定义事件
//defineEmits方法不需要引入直接使用
let $emit = defineEmits(['xxx'])const handler = ()=>{//第一个参数:事件类型 第二个|三个|N参数即为注入数据$emit('xxx','参数1','参数2');
}</script>
<style scoped>.Child2{background-color: red;height: 100px;width: 100px;}.Child2-title{color: white;}</style>
defineEmits
是 Vue 3 中用于在 Composition API(组合式 API)中定义组件所触发的事件的一种方式,尤其是在使用 <script setup>
语法时非常常见。
作用:
defineEmits
允许你声明一个组件可以向外触发的自定义事件。它返回一个函数,你可以用这个函数来触发事件并传递参数。
defineEmits
接收一个数组,数组中的每一项是组件会触发的事件名。emit
是一个函数,用于触发这些事件,并传递数据。
父组件注入子组件2
<template><div class="props-text"><h1>custom event 自定义事件</h1><h1>我是父组件</h1><hr><!--vue2框架当中:这种写法自定义事件,可以通过.native修饰符变为原生DOM事件vue3框架下面写法其实即为原生DOM事件vue3:原生的DOM事件不管是放在标签身上、组件标签身上都是原生DOM事件 --><Child1 @click="handler2(1,2,$event)"></Child1><hr><!-- 自定义事件 --><Child2 @xxx="handler3" @click="handler4"></Child2></div>
</template>
<script setup>
import Child1 from './Child1.vue'
import Child2 from './Child2.vue'const handler1 = () => {console.log('父组件点击了')
}
const handler2 = (a,b,$event) => {console.log(a,b,$event)
}const handler3 = (paramsa,paramsb) => {console.log(paramsa,paramsb)
}const handler4 = () => {alert('Dom原生事件 被触发了');
}</script><style scoped>
.props-text {
width: 400px;
height: 400px;
background-color: burlywood;
}
</style>
控制台输出
并且弹框 弹框内容为 Dom原生事件 被触发了
如果你在组件2中 click添加到自定义事件 则click原生dom变成了自定义事件
子组件代码
<template><div><div class="Child2"><div class="Child2-title">Child2</div><button @click="handler">点击我触发方法xxx</button></div></div>
</template>
<script setup>
//利用defineEmits方法返回函数触发自定义事件
//defineEmits方法不需要引入直接使用
let $emit = defineEmits(['xxx','click'])const handler = ()=>{//第一个参数:事件类型 第二个|三个|N参数即为注入数据$emit('xxx','参数1','参数2');
}</script>
<style scoped>.Child2{background-color: red;height: 100px;width: 100px;}.Child2-title{color: white;}</style>
再次点击父组件的时候 弹框没有了