Vue components通信方式

组件间常用的通信方式

第一种:props方式

======================先停更,有时间写======================

第二种:自定义事件方式

======================先停更,有时间写======================

第三种:全局事件方式

第一步,在main.js文件配置bus对象,目的是找到一个Vue原型,使其可以使用$事件(on,emit等)

new Vue({
  render: h => h(App),
  beforeCreate() {
    Vue.prototype.$bus = this
  }
}).$mount('#app')
​

第二步:在超组件配置$bus

mounted() {
    this.$bus.$on('test',(args)=>{
      //动作行为
      console.log('触发了test事件,收到了参数',args)
    })
  }

第三步:在子组件声明方法,并触发超组件的事件

methods:{
    active(){
        //this.$bus.$emit('需要触发的事件名','传递参数')
        this.$bus.$emit('test','hello world!')
    }
}

完整案例


简述:写一个学校案例,学校(School)为顶级组件,学校组件包含了教室(Class)组件,教室组件包含了学生组件(Student)。

需求:给Student组件设置一个按钮,使其向School组件发送学生的姓名和性别

完整代码:

main.js

import Vue from 'vue'
import App from './App.vue'
​
Vue.config.productionTip = false
​
new Vue({
  render: h => h(App),
  beforeCreate() {
    Vue.prototype.$bus = this
  }
}).$mount('#app')

Student.vue

<template>
  <div id="root">
    <h1>孙子组件:学生</h1>
    <h2>学生姓名:{{name}}</h2>
    <h2>学生性别:{{gender}}</h2>
    <button @click="sendStuName">点我向学校发送姓名和性别</button>
  </div>
</template>
​
<script>
​
export default {
  // eslint-disable-next-line vue/multi-word-component-names
  name: "Student",
  data(){
    return {
      name: '王飞雪',
      gender:'女'
    }
  },
  methods:{
    sendStuName(){
      this.$bus.$emit('getStudentInfo',this.name,this.gender)
    }
  }
}
</script>
​
<style scoped>
#root{
  background-color: orangered;
  margin: 5px;
}
</style>

Class.vue

<template>
  <div>
    <h1>父级组件:班级</h1>
    <h2>班级:{{classNum}}</h2>
    <h2>班主任:{{classHeader}}</h2>
    <hr>
    <Student></Student>
  </div>
</template>
​
<script>
import Student from "@/components/Student";
export default {
  // eslint-disable-next-line vue/multi-word-component-names
  name: "Class",
  data(){
    return{
      classNum:'高二四班',
      classHeader:'刘玮'
    }
  },
  components:{
    Student
  }
}
</script>
​
<style scoped>
​
</style>

School.vue

<template>
  <div class="root">
    <h1>爷爷组件:学校</h1>
    <h2>学校名称:{{name}}</h2>
    <h2>学校地址:{{location}}</h2>
    <hr>
    <Class></Class>
  </div>
​
</template>
​
<script>
​
import Class from "@/components/Class";
export default {
  // eslint-disable-next-line vue/multi-word-component-names
  name: "School",
  data(){
    return{
      msg:'你好啊!',
      name:'尚硅谷',
      location:'北京'
    }
  },
  components:{
    Class
  },
  mounted() {
    this.$bus.$on('getStudentInfo',(arg1,arg2)=>{
      console.log('触发了getStudentInfo事件,学生的姓名是:',arg1,'学生的性别是:',arg2)
    })
  }
}
</script>
​
<style scoped>
.root{
  margin: 5px;
  background-color: #42b983;
}
</style>

App.vue

<template>
  <div id="app">
    <h2>西安东仪中学。我是Vue组件</h2>
    <School></School>
  </div>
</template>
​
<script>
import School from "@/components/School";
export default {
  name: 'App',
  components: {
    // eslint-disable-next-line vue/no-unused-components
    School:School,
  }
}
</script>
​
<style>
#app {
  background-color: grey;
}
</style>

运行结果:点击按钮后

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值