组件间父组件和子组件通信可以直接使用组件标签传值,props进行接收数据;
1、父传子:父组件直接给子组件标签传递值,子组件通过props进行接收;
2、子传父:父组件给子组件传递一个本地(带参数)回调,子组件接收回调,然后把自己的数据以参数形式传递给父组件!
3、任意间组件通信(兄弟组件):全局事件总线、消息订阅与发布
子传父代码演示:
app组件:
```css
<template>
<div class="app">
<h1>{{msg}}</h1>
<School :getSchoolName="getSchoolName"/>
<Student/>
</div>
</template>
<script>
import School from './components/School'
import Student from './components/Student'
export default {
name: 'App',
components: {
School,
Student
},
data(){
return{
msg:'你好!'
}
},
methods:{
getSchoolName(name){
console.log('app收到了schoole的数据:',name)
}
}
}
</script>
<style>
.app{
background-color: bisque;
}
</style>
school组件:
<template>
<div class="school">
<h2>学校名 : {{name}}</h2>
<button @click="sendSchoolName">把学校名给app</button>
</div>
</template>
<script>
export default {
name:'Student',
props:['getSchoolName'],
data(){
return{
name:'尚硅谷',
}
},
methods:{
sendSchoolName(){
this.getSchoolName(this.name)
}
}
}
</script>
<style scoped>
.school{
background-color: aqua;
}
</style>
总结:谁接收数据,回调就写在哪里!
一、组件自定义事件
参考:https://cn.vuejs.org/v2/guide/components-custom-events.html
第一种写法: 标签上使用v-on(或简写符@)绑定,使用组件标签时,就是创建一个vuecomponent,则改事件会加在vc上
给哪个标签绑定的事件,就在哪里写该事件的触发代码
app:
<template>
<div class="app">
<h1>{{msg}}</h1>
<School :getSchoolName="getSchoolName"/>
<Student v-on:atguigu="getStudentName"/>
</div>
</template>
<script>
import School from './components/School'
import Student from './components/Student'
export default {
name: 'App',
components: {
School,
Student
},
data(){
return{
msg:'你好!'
}
},
methods:{
getSchoolName(name){
console.log('app收到了schoole的数据:',name)
},
getStudentName(name){
console.log('app收到了student的数据:',name)
}
}
}
</script>
<style>
.app{
background-color: bisque;
}
</style>
student:
<template>
<div class="student">
<h2>学生姓名 : {{name}}</h2>
<h2>学生性别: {{sex}}</h2>
<button @click="sendStudentName">把学生名给app</button>
</div>
</template>
<script>
export default {
name:'Student',
data(){
return{
name:'张三',
sex:'男'
}
},
methods:{
sendStudentName(){
// 触发Student组件实例上的stguigu事件
this.$emit('atguigu',this.name)
}
}
}
</script>
<style scoped>
.student{
background-color:aqua;
padding: 5px;
}
</style>
第二种写法:在mounted钩子中使用this.$refs去拿到student组件实例对象,然后给他绑定自定义事件atguigu,回调为:getStudentName
this. r e f s . s t u d e n t . refs.student. refs.student.on(‘atguigu’,this.getStudentName)
app组件:
<template>
<div class="app">
<h1>{{msg}}</h1>
<School :getSchoolName="getSchoolName"/>
<!-- <Student v-on:atguigu="getStudentName"/> -->
<Student ref="student"/>
</div>
</template>
<script>
import School from './components/School'
import Student from './components/Student'
export default {
name: 'App',
components: {
School,
Student
},
data(){
return{
msg:'你好!'
}
},
methods:{
getSchoolName(name){
console.log('app收到了schoole的数据:',name)
},
getStudentName(name){
console.log('app收到了student的数据:',name)
}
},
mounted(){
this.$refs.student.$on('atguigu',this.getStudentName)
}
}
</script>
<style>
.app{
background-color: bisque;
}
</style>
student组件:
<template>
<div class="student">
<h2>学生姓名 : {{name}}</h2>
<h2>学生性别: {{sex}}</h2>
<button @click="sendStudentName">把学生名给app</button>
</div>
</template>
<script>
export default {
name:'Student',
data(){
return{
name:'张三',
sex:'男'
}
},
methods:{
sendStudentName(){
// 触发Student组件实例上的stguigu事件
this.$emit('atguigu',this.name)
}
}
}
</script>
<style scoped>
.student{
background-color:aqua;
padding: 5px;
}
</style>
自定义事件解绑:this.$off()
一般会在销毁钩子中解绑自定义的事件
给谁绑的自定义事件,就给谁解绑:
student:
<template>
<div class="student">
<h2>学生姓名 : {{name}}</h2>
<h2>学生性别: {{sex}}</h2>
<button @click="sendStudentName">把学生名给app</button>
<button @click="unbind">解绑atguigu事件</button>
<button @click="death">销毁当前student组件的实例对象</button>
</div>
</template>
<script>
export default {
name:'Student',
data(){
return{
name:'张三',
sex:'男'
}
},
methods:{
sendStudentName(){
// 触发Student组件实例上的stguigu事件
this.$emit('atguigu',this.name)
this.$emit('demo')
},
unbind(){
// this.$off('atguigu')//解绑一个自定义事件
this.$off(['atguigu','demo'])//解绑多个自定义事件
// this.$off(['atguigu','demo'])//解绑所有的自定义事件
},
death(){
this.$$destroy() //销毁了当前的student对象,销毁后所有的student实例的自定义事件全都不奏效了
}
}
}
</script>
<style scoped>
.student{
background-color:aqua;
padding: 5px;
}
</style>
组件使用原生事件:.native
<Student ref=“student” @click.native=“show”/>
app:
<template>
<div class="app">
<h1>{{msg}}</h1>
<School :getSchoolName="getSchoolName"/>
<!-- <Student v-on:atguigu="getStudentName"/> -->
<Student ref="student" @click.native="show"/>
</div>
</template>
<script>
import School from './components/School'
import Student from './components/Student'
export default {
name: 'App',
components: {
School,
Student
},
data(){
return{
msg:'你好!'
}
},
methods:{
getSchoolName(name){
console.log('app收到了schoole的数据:',name)
},
getStudentName(name){
console.log('app收到了student的数据:',name)
},
demo(){
console.log('demo绑定')
},
show(){
alert(123)
}
},
mounted(){
this.$refs.student.$on('atguigu',this.getStudentName)
this.$refs.student.$on('demo',this.demo)
}
}
</script>
<style>
.app{
background-color: bisque;
}
</style>