Vue多层组件之间数据通信

1.通过全局事件总线来通信:

import Vue from 'vue'
import App from './App.vue'
 
Vue.config.productionTip = false
 
new Vue({
  render: h => h(App),
  //安装全局事件总线,就是在创建之前,给Vue实例添加一个对象,并将Vue实例赋值给这个对象,使这个对象可以作为Vue实例使用
  beforeCreate() {
    Vue.prototype.$bus = this
  }
}).$mount('#app')

组件发送数据:

<template>
<div>
<!--  这个子组件是用来发送数据的-->
<!--  将点击事件绑定到方法,方法中出发一个自定义事件,这个自定义事件是绑定在事件总线上的-->
  <button type="button" @click="sendData">传递数据</button>
</div>
</template>
 
<script>
export default {
  data(){
    return {
      name:'s_com1'
    }
  },
  methods:{
    sendData(){
      //这个事件名为send的事件是绑定在事件总线上的,在这个子组件上触发之后,实现了提供数据的功能
      this.$bus.$emit('send',this.name)
    }
  }
}
</script>
 
<style scoped>
 
</style>

组件接收:

<template>
<div>
<!--  这个子组件是用来接受数据的-->
{{count}}
</div>
</template>
 
<script>
export default {
  data(){
    return {
      count:''
    }
  },
  mounted() {
    //在这个子组件中,同样使用事件总线绑定了一个事件,事件名就是发送数据的自定义事件名
    //这个绑定事件的语句要写在mounted(钩子函数)内,表示在执行方法之前,首先执行钩子函数中的内容
    //在这个钩子函数中绑定了这个自定义事件,就可以接收到来自这个定义事件所发送的数据
    //数据的接受使用的是一个方法接受
    this.$bus.$on('send',this.test)
  },
  methods:{
    //接收数据的方法,方法中的形参就是接收到的来自其他组件的数据
    //在方法内部可以对数据进行逻辑操作,这里只是简单的将数据存储到组件中的数据中进行展示而已
    test(data){
      this.count = data
    }
  }
}
</script>
 
<style scoped>
 
</style>

2.$attrs / $listeners(多层嵌套组件传递数据或者方法)

使用过程中,如果有存在中间的组件截取了props,那么这个值将不会继续向下传递。相反传递给父元素则没有这个问题。

// parent组件
<template>
  <div>
    // 注意:不仅可以向后代组件传递数据,还可以传递方法
    <Item :message="msg" :click-function="clickFunction" @getMsg="getMsg"></Item>
  </div>
</template>
<script>
import Item from './components/Son.vue';
export default {
  components: {Item},
  data () {
    return {
      msg: 'parent组件的数据'
    };
  },
  methods: {
    clickFunction () {
      return '返回个啥呢';
    },
    getMsg(val){
      console.log(val)
    }
  }
};
</script>
// 子组件
<template>
  <div>
    // $props监听数据,$listeners监听方法
    <Child v-bind="$attrs" v-on="$listeners" />
  </div>
</template>
<script>
import Child from './Child.vue';
export default {
  components: {Child},
  // 注意:这里的props声明什么,就可以传递给后代组件什么
  props: {
    message: {
      type: String,
      default: ''
    },
    clickFunction: {
      type: Function,
      default: () => {}
    }
  }
};
</script>
// 孙子组件
<template>
  <div>
    {{message}}
    <el-button @click="handleClick">点击</el-button>
  </div>
</template>
<script>

export default {
  props: {
    message: {
      type: String,
      default: ''
    },
    clickFunction: {
      type: Function,
      default: () => {}
    }
  },
  methods: {
    handleClick () {
      let res = this.clickFunction();
      console.log(res);
      this.$emit('getMsg','传递')
    }
  }
};
</script>

3.provider和inject,传递响应式:

provider(){
    return {
        obj:this.obj, //通过浅拷贝达到响应式
        message:()=>this.message //用函数的形式返回一个响应式数据
    }
}
 
inject:["obj","message"] //这里message不再是变量而是函数,使用时要加小括号,调用函数,可配合计算属性使用
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Goat恶霸詹姆斯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值