组件自定义事件
区别于js内部事件的存在,比如点击事件(click),键盘事件(keyup)等等js都是内部事件。我们自定义的事件,是给组件用的。
案例分析
我们子组件给父组件传参数的过程是,父组件给子组件一个函数,然后子组件传递参数的时候去调用这个函数。我们设立一个学校和学生的名称案例,点击页面上的按钮,控制台就会打印出App收到了学校名。
//App.vue代码
<template>
<div class="app">
<h1>{{ msg }}</h1>
<!-- 把定义好的函数传递给子组件 -->
<School :getSchoolName="getSchoolName" />
<Student />
</div>
</template>
<script>
import Student from "./components/Student";
import School from "./components/School";
export default {
name: "App",
components: { School, Student },
data() {
return {
msg: "你好啊!",
};
},
methods: {
//给子组件设立一个函数,用来向App父组件传参数
getSchoolName(name) {
console.log("App收到了学校名:", name);
},
},
};
</script>
<style scoped>
.app {
background-color: gray;
}
</style>
//school代码
<template>
<div class="school">
<h2>学校名称:{{ name }}</h2>
<h2>学校地址:{{ address }}</h2>
<button @click="sendSchoolName">把学校名给App</button>
</div>
</template>
<script>
export default {
name: "School",
//声明接收父组件设立的传参函数
props: ["getSchoolName"],
data() {
return {
name: "尚硅谷",
address: "北京",
};
},
methods: {
sendSchoolName() {
this.getSchoolName(this.name);
},
},
};
</script>
<style scoped>
.school {
background-color: skyblue;
padding: 5px;
}
</style>
输出效果如下:
应用自定义事件
在App.vue里给studen组件标签的实例对象绑定一个自定义事件,然后定义事件响应后的执行函数,然后在student.vue里设计一按钮,点即该按钮 就会触发我们刚刚自定义的事件,把学生的名字以及多个参数发送给App.vue,我们在控制台可以看到执行函数打印输出的效果。
//App.vue代码
<template>
<div class="app">
<h1>{{ msg }}</h1>
<!-- 把定义好的函数传递给子组件 -->
<School :getSchoolName="getSchoolName" />
<!-- 使用v-on绑定一个自定义事件atguigu给student的实例对象 -->
<Student v-on:atguigu="getStudentName" />
</div>
</template>
<script>
import Student from "./components/Student";
import School from "./components/School";
export default {
name: "App",
components: { School, Student },
data() {
return {
msg: "你好啊!",
};
},
methods: {
//给子组件设立一个函数,用来向App父组件传参数
getSchoolName(name) {
console.log("App收到了学校名:", name);
},
//自定义事件的响应函数,可以接受多个参数xyz
getStudentName(name,x,y,z) {
console.log("demo被调用了",name,x,y,z);
},
},
};
</script>
<style scoped>
.app {
background-color: gray;
}
</style>
//student.vue代码
<template>
<div class="student">
<h2>学生姓名:{{name}}</h2>
<h2>学生性别:{{sex}}</h2>
<h2>当前求和为:{{number}}</h2>
<button @click="add">点我number++</button>
<button @click="sendStudentlName">把学生名给App</button>
<button @click="unbind">解绑atguigu事件</button>
<button @click="death">销毁当前Student组件的实例(vc)</button>
</div>
</template>
<script>
export default {
name:'Student',
data() {
return {
name:'张三',
sex:'男',
number:0
}
},
methods: {
add(){
console.log('add回调被调用了')
this.number++
},
sendStudentlName(){
//触发Student组件实例身上的atguigu事件,发送名字和多个数字
this.$emit('atguigu',this.name,666,888,900)
// this.$emit('demo')
// this.$emit('click')
},
unbind(){
this.$off('atguigu') //解绑一个自定义事件
// this.$off(['atguigu','demo']) //解绑多个自定义事件
// this.$off() //解绑所有的自定义事件
},
death(){
this.$destroy() //销毁了当前Student组件的实例,销毁后所有Student实例的自定义事件全都不奏效。
}
},
}
</script>
<style scoped>
.student{
background-color: pink;
padding: 5px;
margin-top: 30px;
}
</style>
输出效果图如下
解绑自定义事件
我们给谁绑定的自定义事件,就在谁身上解绑,上文说到我们是给student中的实例对象绑定了,那么这里在增加一个按钮,点击后就会解绑atguigu事件
student.vue
<template>
<div class="student">
<h2>学生姓名:{{ name }}</h2>
<h2>学生性别:{{ sex }}</h2>
<h2>当前求和为:{{ number }}</h2>
<button @click="add">点我number++</button>
<button @click="sendStudentlName">把学生名给App</button>
<button @click="unbind">解绑atguigu事件</button>
<button @click="death">销毁当前Student组件的实例(vc)</button>
</div>
</template>
<script>
export default {
name: "Student",
data() {
return {
name: "张三",
sex: "男",
number: 0,
};
},
methods: {
add() {
console.log("add回调被调用了");
this.number++;
},
sendStudentlName() {
//触发Student组件实例身上的atguigu事件,发送名字和多个数字
this.$emit("atguigu", this.name, 666, 888, 900);
// this.$emit('demo')
// this.$emit('click')
},
unbind() {
this.$off("atguigu"); //解绑一个自定义事件
// this.$off(['atguigu','demo']) //解绑多个自定义事件
// this.$off() //解绑所有的自定义事件
},
death() {
this.$destroy(); //销毁了当前Student组件的实例,销毁后所有Student实例的自定义事件全都不奏效。
},
},
};
</script>
<style scoped>
.student {
background-color: pink;
padding: 5px;
margin-top: 30px;
}
</style>
销毁vm
我们在main.js中添加生命周期函数mounted,当页面所有东西挂载结束后,定时3秒,销毁所有vm实例,那么就等于所有的组件也销毁了,相关的自定义事件也被销毁了,原生的事件不会被销毁,但是不会被在页面上显示出效果来。
//main.js代码
//引入Vue
import Vue from 'vue'
//引入App
import App from './App.vue'
//关闭Vue的生产提示
Vue.config.productionTip = false
//创建vm
new Vue({
el: '#app',
render: h => h(App),
//生命周期的挂载完毕函数
mounted() {
//定时3秒钟,启动销毁vm实例对象
setTimeout(() => {
this.$destroy()
}, 3000)
},
})