目录
Vue子组件向父组件传递数据的通信方式有很多,我这里列举了三种。
方法一:使用props实现
方法二:使用v-on或者@,给组件Student的实例对象绑定一个自定义事件实现
方法三:使用ref,给组件Student的实例对象绑定一个自定义事件实现
Vue子组件向父组件传递数据的通信方式有很多,我这里列举了三种。
方法一:使用props实现
父组件向子组件通过props传递一个函数,子组件触发事件时,调用这个函数,把自己的数据传给父组件,实质是进行了父子之间的相互通信
案例:App是父组件,下面有一个子组件School,实现功能如下:点击School组件的按钮,把自己的数据:学校名称name,传给父组件App,父组件把数据在控制台打印出来
第一步:在父组件App.vue的methods中,配置一个函数getSchoolName(),形参是name,将传进去的子组件的学校名字打印在控制台上
<template>
<div class="app">
<h1>{{ msg }}</h1>
<School :getSchoolName="getSchoolName"></School>
<Student></Student>
</div>
</template>
<script>
// 引入组件
import School from "./components/School";
import Student from "./components/Student";
export default {
name: "App",
components: {
School,
Student,
},
data() {
return {
msg: "我是父组件App",
};
},
methods: {
getSchoolName(name){
console.log("App收到了School的name",name)
}
},
};
</script>
<style >
.app {
background-color: lightblue;
padding: 5px;
}
</style>
代码中的核心:
第二步:将父组件App.vue的函数getSchoolName,通过props,传给子组件School.vue
第三步:子组件中触发单击事件,在事件响应时,获取对应的name数据,再调用父组件传过来的方法,将name数据传进去
子组件 School组件:School.vue
<template>
<!-- 组件的结构 -->
<div id="demo1">
<h2>我是App的子组件School</h2>
<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>
/* 组件样式 */
#demo1{
background-color: #bfa;
padding: 5px;
}
</style>
代码中的核心:
点击按钮,查看控制台展示的效果
方法二:使用v-on或者@,给组件Student的实例对象绑定一个自定义事件实现
案例:App是父组件,下面有一个子组件Student,实现功能如下:点击Student组件的按钮,把自己的数据:学生名称name,传给父组件App,父组件把数据在控制台打印出来
第一步:在父组件App.vue中,给子组件Student的实例对象绑定一个自定义事件
<template>
<div class="app">
<h1>{{ msg }}</h1>
<!-- 通过父组件给子组件传递函数类型的props,实现:子向父传递数据 -->
<School :getSchoolName="getSchoolName"></School>
<!-- 给组件Student的实例对象绑定一个自定义事件,实现:子向父传递数据 -->
<Student v-on:demo="getStudentName"></Student>
</div>
</template>
<script>
// 引入组件
import School from "./components/School";
import Student from "./components/Student";
export default {
name: "App",
components: {
School,
Student,
},
data() {
return {
msg: "我是父组件App",
};
},
methods: {
getSchoolName(name){
console.log("App收到了School的name",name)
},
getStudentName(name){
console.log('App收到了Student的name',name)
}
},
};
</script>
<style >
.app {
background-color: lightblue;
padding: 5px;
}
</style>
核心代码,下图的1中的v-on可以简写为@,即v-on:demo与@demo等价
第二步:在子组件Student.vue中,绑定单击响应函数,触发Student组件实例对象身上的demo事件
<template>
<!-- 组件的结构 -->
<!--
功能
点击Student组件的按钮,把自己的数据:学生名称,交给父组件App
-->
<div id="demo">
<h2>我是App的子组件Student</h2>
<h2>学生姓名:{{name}}</h2>
<h2>学生年龄:{{age}}</h2>
<button @click="sendStudentName">点我将学生姓名传给App</button>
</div>
</template>
<script>
// 组件交互相关,如数据、方法
export default {
name:'Student', //一般要和文件名字一致
data() {
return {
name:'湖大学子',
age:18
}
},
methods: {
sendStudentName(){
// 触发Student组件实例对象身上的demo事件
this.$emit('demo',this.name)
}
},
}
</script>
<style >
/* 组件样式 */
#demo{
background-color: pink;
padding: 5px;
margin-top: 30px;
}
</style>
核心代码
点击按钮,查看控制台展示的效果:
上述两种方法的区别:
相同点:二者都在父组件中配置了回调函数,供子组件使用
不同点:
方法一,使用props,父组件将回调函数传给子组件,子组件接收该函数,然后亲自调用该函数
方法二,使用$emit,子组件触发事件的响应函数,执行该回调函数,子组件不需要接收该函数,也不用亲自调用
方法三:使用ref,给组件Student的实例对象绑定一个自定义事件实现
还是针对子组件Student.vue和父组件App.vue,进行演示,不需要修改子组件Student.vue。
只需要修改父组件App.vue,通过
ref
属性 为子组件Student.vue赋予一个 ID 引用,通过this.$refs.student,就可以拿到子组件的实例对象
<template>
<div class="app">
<h1>{{ msg }}</h1>
<!-- 通过父组件给子组件传递函数类型的props,实现:子向父传递数据 -->
<School :getSchoolName="getSchoolName"></School>
<!-- 使用v-on或者@,给组件Student的实例对象绑定一个自定义事件,实现:子向父传递数据 -->
<!-- <Student v-on:demo="getStudentName"></Student> -->
<!-- 使用ref,给组件Student的实例对象绑定一个自定义事件,实现:子向父传递数据 -->
<Student ref="student"></Student>
</div>
</template>
<script>
// 引入组件
import School from "./components/School";
import Student from "./components/Student";
export default {
name: "App",
components: {
School,
Student,
},
data() {
return {
msg: "我是父组件App",
};
},
methods: {
getSchoolName(name){
console.log("App收到了School的name",name)
},
getStudentName(name){
console.log('App收到了Student的name',name)
}
},
mounted() {
this.$refs.student.$on('demo',this.getStudentName)
},
};
</script>
<style >
.app {
background-color: lightblue;
padding: 5px;
}
</style>
核心代码:
点击按钮,查看控制台展示的效果:
使用ref的方法三更加灵活,可以实现更多的功能,比如,一段时间之后,再向父组件传递数据,解决办法是在mounted中写一个定时器回调函数,如,5秒之后再打印输出
方法一和二则不能这样灵活
看完以上三种方法,你学会了吗?