常见的组件通信的方式的使用

什么是组件通信------就是指组件与组件之间的数据传递

组件的数据是独立的,无法直接访问其他组件的数据

想用其他组件的数据------组件通信

组件关系分类

各部分完整代码及行内注释都在模块下面

1.父子关系

props和$emit

1.父组件通过props将数据传递给子组件

第一步:给子组件以 添加属性 的方式传递

第二步:子组件内部通过 props:[] 接收

第三步:直接使用props的值

2.子组件利用$emit通知父组件修改更新

第一步:$emit触发事件,给父组件发送消息通知

第二步:父组件监听事件

第三步:提供处理函数,形参中获取参数

注意名字不要写错了

完整代码参考这里

App.vue

<template>
  <div id="app" class="fat">
    <span>我是父组件 App</span>
    <!-- 父传子第一步 :
      给子组件以添加属性的方式传递-->

      <!-- 子向父传递,2.父组件监听事件 -->
      <!-- @changeTitle="随便起一个复合命名规范的名字就可以" -->
    <Son :title="myTitle" @changeTitle="learnChange"></Son>
  </div>
</template>

<script>
// 在export外面导入.vue文件
import Son from "./components/Son.vue";
export default {
  name: 'App',
  components: {
    Son,
  },
  data() {
    return {
      myTitle:'天使神'
    }
  },
  methods:{
    //子向父传递,3.提供处理函数,形参中获取参数
    learnChange(title){
      this.myTitle=title;
    }
  }
}
</script>

<style scoped>
.fat{
  border: 3px solid blue;
  margin:30px;
  padding: 30px;
}
</style>

Son.vue

<template>
  <div class="son">
    <span>我是子组件 Son ---</span>
    <!-- 父传子第三步:直接使用props的值 -->
    {{ title }}
    <br><br>
    <button @click="changeTitle">修改title值</button>
  </div>
</template>

<script>
export default {
    name:'Son-Child',
    // 父传子第二步:子组件内部通过 props:[] 接收
    props:['title'],
    methods:{
      changeTitle(){
        // 子向父传递,发出请求
        //1.$emit触发事件,给父组件发送消息通知
        this.$emit('changeTitle','修罗神才是最牛的')
      }
    }
}
</script>

<style scoped>
.son{
    border: 3px solid red;
    margin: 20px;
    padding: 20px;
}
</style>

2.非父子关系

1>provide&inject

provide&inject作用:跨层级共享数据

1.父组件provide提供数据

2.子/孙组件inject取值使用

具体代码的注释

完整代码参考这里

App.vue

<template>
  <div class="app">
    我是APP组件
    <button @click="change">修改数据</button>
    <SonA></SonA>
    <SonB></SonB>
  </div>
</template>

<script>
import SonA from './components/SonA.vue'
import SonB from './components/SonB.vue'
export default {
  components: {
    SonA, SonB,
  },
  provide() {
    return {
      // 简单类型 是非响应式的
      color: this.color,
      // 复杂类型 是响应式的
      userInfo: this.userInfo,
    }
  },
  data() {
    return {
      color: 'blue',
      userInfo: {
        name: 'MoMoCi',
        age: 18,
      },
    }
  },
  methods: {
    change() {
      this.color = 'red'
      this.userInfo.name = 'Chemo'
    },
  },
  
}
</script>

<style>
  .app {
    width: 400px;
    padding: 20px;
    border: 3px solid #000;
    border-radius: 6px;
    margin: 10px;
  }
</style>

SonA.vue

<template>
  <div class="SonA">
    子组件A
    <GrandSon></GrandSon>
  </div>
</template>

<script>
import GrandSon from '../components/GrandSon.vue'
export default {
  components: {
    GrandSon
  },
}
</script>

<style scoped>
.SonA{
  height: 100px;
  width: 300px;
  margin: 30px;
  padding: 20px;
  border: 3px solid black;
}
</style>

SonB.vue

<template>
  <div class="SonB">
    子组件B
  </div>
</template>

<script>
export default {

}
</script>

<style scoped>
.SonB{
  height: 100px;
  width: 300px;
  margin: 30px;
  padding: 20px;
  border: 3px solid black;
}
</style>

GrandSon.vue

<template>
  <div class="grandson">
    孙子组件
    <br>
    {{ color }} -{{ userInfo.name }} - {{ userInfo.age }}
  </div>
</template>

<script>
export default {
  inject: ['color', 'userInfo'],
}
</script>

<style scoped>
.grandson{
    width: 200px;
    height: 40px;
    padding: 10px;
    border: 3px solid red;
}
</style>

2>eventbus

非父子组件之间,进行简易消息传递。

1.创建一个都能访问的事件总线(空Vue实例)utils/EventBus.js

2.A组件(接收方),监听Bus实例的事件

3.B组件(发送方),触发Bus实例的事件

具体代码的注释

完整代码参考这里

utils/EventBus.js

// 1.创建一个都能访问到的事件总线(空的 vue 实例)
import Vue from 'vue'
const Bus = new Vue()
export default Bus

App.vue

<template>
  <div>
    <BaseA></BaseA>
    <BaseB></BaseB>
    <BaseC></BaseC>
  </div>
</template>

<script>
import BaseA from './components/BaseA.vue'
import BaseB from './components/BaseB.vue'
import BaseC from './components/BaseC.vue'

export default {
  components: {
    BaseA,BaseB,BaseC
  }
}
</script>

BaseA.vue

<template>
  <div class="base-a">
    我是A组件 (接收者)
    <p>{{ msg }}</p>
  </div>
</template>

<script>
import Bus from '../utils/EventBus'
export default {
  created(){
    // 2.在A组件(接收方),进行监听Bus的事件(订阅消息)
    Bus.$on('sendMsg',(msg) => {
      console.log(msg);
      this.msg = msg;

    })
  },
  data(){
    return{
      msg:''
    }
  }
}
</script>

<style>
.base-a{
  box-sizing: border-box;
  height: 200px;
  width: 400px;
  margin: 30px;
  padding: 20px;
  font-size: 30px;
  border: 5px solid black;
}
</style>

BaseB.vue

<template>
  <div class="base-b">
    我是B组件 (发送者)
    <button @click="send">发送讯息</button>
  </div>
</template>

<script>
import Bus from '../utils/EventBus'
export default {
  methods:{
    send(){
      // 3.B组件(发送方),进行监听事件的方式传递参数(发布消息)
      Bus.$emit('sendMsg','咚巴拉呀咚巴咚巴拉')
    }
  }
}
</script>

<style lang="less">
.base-b{ 
  box-sizing: border-box;
  height: 200px;
  width: 400px;
  margin: 30px;
  padding: 20px;
  font-size: 30px;
  border: 5px solid black;
  button{
    width: 90px;
    height: 30px;
    font-size: 16px;
  }
}
</style>

BaseC.vue

<template>
  <div class="base-c">
    我是C组件 (接收者)
    <p>{{ msg }}</p>
  </div>
</template>

<script>
import Bus from '../utils/EventBus'
export default {
  created(){
    // 2.在C组件(接收方),进行监听Bus的事件(订阅消息)
    Bus.$on('sendMsg',(msg) => {
      console.log(msg);
      this.msg = msg;
    })
  },
  data(){
    return{
      msg:''
    }
  }
}
</script>

<style>
.base-c{
  box-sizing: border-box;
  height: 200px;
  width: 400px;
  margin: 30px;
  padding: 20px;
  font-size: 30px;
  border: 5px solid black;
}
</style>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值