一、什么是自定義事件?
- 自定義事件是 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>
再次點擊父組件的時候 彈框沒有了