案例引入
我们前面在TodoList经典案例中提到过,如果父组件要向子组件传递数据,我们可以使用props。而如果子组件要向父组件传递数据,我们可以先在父组件中定义好方法,使用props传递给子组件,然后让子组件去调用它。
现在我们多了一种子组件向父组件传递数据的方法,那就是自定义事件
。
现在我们完成一个小案例,分别使用两种不同的方式,将子组件中的数据传递给父组件
首先我们使用props的方法完成学校名称的传递,代码实现如下:
App组件:
<template>
<div>
<h2 ref="title" >欢迎来到{{n}}</h2>
<hr>
<SchoolName :getSchoolName="getSchoolName"></SchoolName>
<StudentName ></StudentName>
</div>
</template>
<script>
import SchoolName from "@/components/School";
import StudentName from "@/components/Student";
export default {
components:{
SchoolName,
StudentName
},
data(){
return {
n:'CSDN'
}
},
methods:{
getSchoolName(name){
console.log('App组件已经收到了学校的名字:',name)
}
}
}
</script>
<style>
</style>
School组件:
<template>
<div class="demo">
<h2>学校名称:{{name}}</h2>
<h2>学校地址:{{address}}</h2>
<button @click="getSchoolName(name)">点击将学校名称交给父组件App</button>
<hr>
</div>
</template>
<script>
export default {
name:'DongBei',
data(){
return {
name:'NEFU',
address:'哈尔滨',
}
},
props:['getSchoolName'],
}
</script>
<style >
.demo {
background-color: yellow;
}
</style>
然后我们使用组件的自定义事件来完成学生名称数据的传递:
①首先我们使用v-on
指令给student组件身上绑定事件(准确点说是给student组件的实例对象vc上绑定了事件)。事件的名字我们随便取,这里我使用stuName。
②然后我们完善一下回调函数:
<template>
<div>
<h2 ref="title" >欢迎来到{{n}}</h2>
<hr>
<SchoolName :getSchoolName="getSchoolName"></SchoolName>
<StudentName v-on:stuName="getStudentName"></StudentName>
</div>
</template>
<script>
import SchoolName from "@/components/School";
import StudentName from "@/components/Student";
export default {
components:{
SchoolName,
StudentName
},
data(){
return {
n:'CSDN'
}
},
methods:{
getSchoolName(name){
console.log('App组件已经收到了学校的名字:',name)
},
getStudentName(name){
console.log('App组件已经收到了学生的名字:',name)
}
}
}
</script>
③完成了这些我们很自然地就可以想到,我们如何去触发我们的自定义事件呢?因为我们的自定义事件绑定在了Student组件的实例对象上,那么我们就在Student的实例对象上去对他进行触发。
这里我们就要使用到事件触发语句$emit(eventName)
来触发事件,括号中还可以紧跟一个参数用来给事件回调函数传参:
Student组件
<template>
<div class="demo">
<h2 class="stu" >学生名称:{{name}}</h2>
<h2 >学生年纪:{{age}}</h2>
<button @click="studentNameGetter(name)">点击将学生名称交给父组件App</button>
</div>
</template>
<script>
export default {
name:'MyStudent',
data(){
return {
name:'张三',
age:18
}
},
methods:{
studentNameGetter(name){
// 触发Student组件实例身上的stuName事件
this.$emit('stuName',name)
}
}
}
</script>
这里有一个易错点:触发事件的名字不要写成事件回调函数的名字!
注意点:
例如:
我i们可以先试用ref获得Student组件的实例对象,再在这个实例对象上绑定事件。
<template>
<div>
<h2 ref="title" >欢迎来到{{n}}</h2>
<hr>
<SchoolName :getSchoolName="getSchoolName"></SchoolName>
<StudentName ref="Student"></StudentName>
<!-- <StudentName v-on:stuName="getStudentName"></StudentName>-->
<!-- <StudentName @stuName="getStudentName"></StudentName>-->
</div>
</template>
<script>
import SchoolName from "@/components/School";
import StudentName from "@/components/Student";
export default {
components:{
SchoolName,
StudentName
},
data(){
return {
n:'CSDN'
}
},
methods:{
getSchoolName(name){
console.log('App组件已经收到了学校的名字:',name)
},
getStudentName(name){
console.log('App组件已经收到了学生的名字:',name)
}
},
mounted() {
this.$refs.Student.$on('stuName',this.getStudentName)
}
}
</script>
这种绑定方式的存在意义就是他的灵活型很强,我们可以举个例子来体会。
前两种方式进行事件绑定他都是瞬间绑定完成。但是如果现在有一个需求是等几秒钟再绑定(例如等Ajax请求发送完毕回来我们再绑定自定义事件),我们使用前两种方式是完成不了的,此时只能使用上述的方式。
例如现在我们向让它等3秒钟再绑定事件:
<template>
<div>
<h2 ref="title" >欢迎来到{{n}}</h2>
<hr>
<SchoolName :getSchoolName="getSchoolName"></SchoolName>
<StudentName ref="Student"></StudentName>
<!-- <StudentName v-on:stuName="getStudentName"></StudentName>-->
<!-- <StudentName @stuName="getStudentName"></StudentName>-->
</div>
</template>
<script>
import SchoolName from "@/components/School";
import StudentName from "@/components/Student";
export default {
components:{
SchoolName,
StudentName
},
data(){
return {
n:'CSDN'
}
},
methods:{
getSchoolName(name){
console.log('App组件已经收到了学校的名字:',name)
},
getStudentName(name){
console.log('App组件已经收到了学生的名字:',name)
}
},
mounted() {
setTimeout(() => {
this.$refs.Student.$on('stuName',this.getStudentName)
},3000)
}
}
</script>
如果我们想要这个事件只能触发一次:
如果要传递多个数据,有两种方法:
- 直接传一个对象过去
- 使用ES6的…params语法
小总结
父组件是使用 props 传递数据给子组件,但如果子组件要把数据传递回去,就需要使用自定义事件!
我们可以使用 v-on 绑定自定义事件, 每个 Vue 实例都实现了事件接口(Events interface),即:
- 使用 $on(eventName) 监听事件
- 使用 $emit(eventName) 触发事件
另外,父组件可以在使用子组件的地方直接用 v-on 来监听子组件触发的事件。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/122113.html