一、什么是自定义事件?

  • 自定义事件是 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>&nbsp;&nbsp;
      <router-link to="/">index</router-link>&nbsp;&nbsp;
      <router-link to="/props">props</router-link>&nbsp;&nbsp;
      <router-link to="/customevent">custom event</router-link>&nbsp;&nbsp;
     
    </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>

再次点击父组件的时候 弹框没有了

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐