Vue组件的自定义事件$emit
组件上的自定义事件是和组件的自定义属性一样,都是模仿HTML正常的标签,由组件给出事件句柄,由使用组件的父组件提供事件处理函数。组件自定义事件真正触发的地方是在组件模板的标签上,组件自己不提供事件处理函数,将这个处理函数给出一个定义,将这个定义抛给使用组件的父组件,由父组件给出。子组件其他处理函数可以通过组件自定义事件的定义调用这个函数。依照面向对象编程设计的原则,属性自定义事件具有依赖倒置的原则,即依赖抽象,不依赖具体。
组件自定义事件示例:
<script setup lang="ts">
const props=defineProps<{
msg: string,
count:number,
show:boolean,
list:string[],
pfun:Function
}>()
const emits=defineEmits<{
(e:"wait",time:number):void
(e:"change"):void
(e:"append",str:string):void
}>()
let test=()=>{
props.pfun();
emits('wait',2000);
return "props.pfun is called, emits wait is called";
}
console.log(test())
</script>
<template>
<div @click="$emit('change')">
<div>{{ count }}</div>
<div @click="$emit('wait',1000)">{{ msg }}</div>
<div @click="$emit('wait')">{{ show }}</div>
<div @click="$emit('append','appstr')">{{ list }}</div>
</div>
</template>
组件使用示例:
<script setup lang="ts">
import {ref} from "vue"
import HelloWorld from './components/HelloWorld.vue'
const hlist=ref(["hello","wrold","vue"]);
const count=ref(10);
function hpfun(){
console.log("The value is from father component function");
return "The value is from father component function";
}
function waitOnHelloWorld(time:number){
console.log("wait for "+time+" seconds");
count.value+=time;
console.log("count is "+count.value);
}
function appendToList(appstr:string){
hlist.value.push(appstr);
console.log("append is working");
}
function changeHW(){
console.log("change happens")
}
</script>
<template>
<HelloWorld :pfun="hpfun" @change="changeHW" @append="appendToList('world')" @wait="waitOnHelloWorld(10)" :count="count" msg="Yes, You did it!" :show="true" :list="hlist"></HelloWorld>
</template>
从以上案例中可以得出结论:
1、组件的自定义事件可以设置调用时函数的形参类型、形参个数
2、组件定义时可以在模板上绑定自定义事件,事件参数可以添加也可以不添加,这些参数都不起作用
3、组件使用时,只有父组件为组件的自定义事件绑定了事件处理函数,组件上事件才会有效果
4、父组件提供事件处理函数可以提供组件自定义事件规定的参数,也可以提供、不提供、提供超过形参个数的参数
5、组件自定义事件以父组件实际使用时为组件提供的事件处理函数为准