1. 简介
-
一种组件间通信的方式,适用于:子组件 ===> 父组件
-
使用场景:A是父组件,B是子组件,B想给A传数据,那么就要在A中给B绑定自定义事件(事件的回调在A中)。
-
绑定自定义事件:
-
第一种方式,在父组件中:
<Demo @atguigu="test"/>
或<Demo v-on:atguigu="test"/>
-
第二种方式,在父组件中:
<Demo ref="demo"/> ...... mounted(){ this.$refs.xxx.$on('atguigu',this.test) }
-
若想让自定义事件只能触发一次,可以使用
once
修饰符,或$once
方法。
-
-
触发自定义事件:
this.$emit('atguigu',数据)
-
解绑自定义事件
this.$off('atguigu')
-
组件上也可以绑定原生DOM事件,需要使用
native
修饰符。 -
注意:通过
this.$refs.xxx.$on('atguigu',回调)
绑定自定义事件时,回调要么配置在methods中,要么用箭头函数,否则this指向会出问题!
2. demo
2.1 App
<template>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>React App</title>
<link rel="stylesheet" href="index.css" />
</head>
<body>
<div id="root">
<div class="todo-container">
<div class="todo-wrap">
<!-- 通过父组件给子组件传递函数类型的props实现: 子给父传递数据 -->
<School :sendSchoolName="sendSchoolName" />
<hr />
<!-- 通过父组件给子组件绑定一个自定义事件实现: 子给父传递数据(第一种写法,使用@或者v-on) -->
<!-- <Student
@atDingDong="getStudentName"
@atDingDong2="getStudentName2"
/> -->
<Student @atDingDong="getStudentName" />
<hr />
<h2>学生姓名是{{ StudentName }}</h2>
<!-- 通过父组件给子组件绑定一个自定义事件实现: 子给父传递数据(第二种写法,使用ref) -->
<!-- <Student ref="student" /> -->
<!-- 如果给组件绑定原生事件,比如绑定Click,那么都会当成自定义事件,除非加上修饰符native -->
<Student ref="student" @click.native="sendClick" />
</div>
</div>
</div>
</body>
</html>
</template>
<script>
import School from "./components/School.vue";
import Student from "./components/Student.vue";
export default {
name: "App",
data() {
return {
StudentName: "",
};
},
components: { School, Student },
methods: {
sendClick() {
console.log("给Student组件绑定原生事件");
},
sendSchoolName(name) {
console.log(name);
},
getStudentName(name, ...params) {
console.log(name);
this.StudentName = name;
},
// getStudentName2() {
// console.log("getStudentName2 被触发了");
// },
},
mounted() {
this.$refs.student.$on("atDingDong", this.getStudentName);
//谁触发的绑定事件,this就是谁,由于这里是Student组件触发的,所以这里this就是Student,所以下面这种给StudentName赋值就不行
// this.$refs.student.$on("atDingDong", function getStudentName() {
// console.log(name);
// this.StudentName = name;
// });
//下面这种写法,使用的是=> ,由于=> 没有自己的this,于是他向外找,外面是App的vc,于是就可以
// this.$refs.student.$on("atDingDong", (name, ...params) => {
// console.log(name);
// this.StudentName = name;
// });
},
};
</script>
<style>
/*base*/
body {
background: #fff;
}
.btn {
display: inline-block;
padding: 4px 12px;
margin-bottom: 0;
font-size: 14px;
line-height: 20px;
text-align: center;
vertical-align: middle;
cursor: pointer;
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2),
0 1px 2px rgba(0, 0, 0, 0.05);
border-radius: 4px;
}
.btn-danger {
color: #fff;
background-color: #da4f49;
border: 1px solid #bd362f;
}
.btn-danger:hover {
color: #fff;
background-color: #bd362f;
}
.btn:focus {
outline: none;
}
.todo-container {
width: 600px;
margin: 0 auto;
}
.todo-container .todo-wrap {
padding: 10px;
border: 1px solid #ddd;
border-radius: 5px;
}
</style>
2.2 Student
<template>
<div>
<h2>学生名称为{{ StudentName }}</h2>
<h2>学生地址为{{ StudentAddress }}</h2>
<button @click="sendName">将学生名称交给App</button>
<button @click="unBindAtDingDong">解绑AtDingDong事件</button>
<button @click="death">点我销毁当前实例</button>
</div>
</template>
<script>
export default {
name: "Student",
data() {
return {
StudentName: "张三",
StudentAddress: "金桥",
};
},
methods: {
sendName() {
// 触发Student组件身上的atDingDong事件
this.$emit("atDingDong", this.StudentName);
// this.$emit("atDingDong2", this.StudentName);
},
unBindAtDingDong() {
//解绑单个事件
// this.$off('atDingDong')
//解绑多个事件
// this.$off(['atDingDong','atDingDong2'])
//解绑所有事件
this.$off();
},
death() {
//销毁了当前Student组件的实例,销毁后Student的VC身上的所有的自定义事件全部失效
this.$destroy();
},
},
};
</script>
<style></style>
2.3 js
<template>
<div>
<h2>学校名称为{{ SchoolName }}</h2>
<h2>学校地址为{{ SchoolAddress }}</h2>
<button @click="sendName">将学校名称交给App</button>
</div>
</template>
<script>
export default {
name: "School",
props:['sendSchoolName'],
data() {
return {
SchoolName: "叮咚大学",
SchoolAddress: "张江",
};
},
methods:{
sendName(){
this.sendSchoolName(this.SchoolName)
}
}
};
</script>
<style></style>