Vue组件通讯方式

1. vue组件通信的方式

  1. prop(父传子)
  2. $emit(子传父)
  3. $attrs 和 $listeners
  4. provide 和 inject
  5. EventBus(事件总线)

1.1 prop

用于父组件向子组件传递数据

父组件

<template>
  <div class="data-analysis">
    // 父组件通过自定义属性userBehaviorList将userBehaviorList传递给子组件
    <dataAnalysisSelect  :userBehaviorList="userBehaviorList" :sceneObj="item.sceneList[0]">
    </dataAnalysisSelect>
  </div>
</template>

子组件

<template>
  <div style="display:flex;margin-top:1px">
    <Select v-model="innerValue.sceneType" style="margin:0 10px;width:220px" @on-change="changeType">
      <Option :value="it.strValue" v-for="it in userBehaviorList" :key="it.value">{{ it.name }}</Option>
    </Select>
    <Select v-model="innerValue.sceneKey" style="margin:0 10px;width: 220px" filterable @on-change="changeSceneKey">
      <Option :value="it.rkey" v-for="(it,index) in sceneKeyList" :key="it.index">{{ it.name }}</Option>
    </Select>
  </div>
</template>

export default {
  props: {
//接收userBehaviorList数组
    userBehaviorList: {
      type: Array, 
      default() {
        return []
      }
    },
    sceneObj: {
      type: Object,
      default() {
        return {}
      }
    }
  },
}

1.2 $emit

父组件自定义事件,子组件主动触发事件并传递数据

父组件

<template>
  <div>
    //父组件自定义事件`@radioChange="radioChange"`
    <Radio v-else-if="formItem.value==4" :formId="formItem.id" v-model="list[formItem.strValue]" :strValue="formItem.strValue" :userList="currentUser" @radioChange="radioChange"></Radio>
  </div>
</template>

子组件

<template>
  <RadioGroup v-model="innerValue" @on-change="changeValue">
    <Radio :label="item.value" v-for="item in radioList" :key="item.id">{{item.name}}</Radio>
  </RadioGroup>
</template>


export default {
  model:{
    event:'changeRadioValue',
    prop:'innerValue'
  },
    methods:{
      changeValue(){
        //子组件通过$emit触发父组件的自定义事件,将所需要传递到数据传给父组件
        this.$emit('radioChange',this.strValue,this.radioList[i].name,this.obj)
    }
  },
}

1.3 attrs 和 listeners

  1. $attrs

包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind=“$attrs” 传入内部组件——在创建高级别的组件时非常有用

  1. $listeners

包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on=“$listeners” 传入内部组件——在创建更高层次的组件时非常有用。
3.attr负责存储属性,listeners负责存储事件,都是以对象的形式存储数据

父组件

<template>
  <div class="home">
    <Child :first="first" :second="second" @getFirst.native="getFirst" @getSecond="getSecond"></Child>
  </div>
</template>

export default {
  components:{Child},
  data(){
    return {
      first:1,
      second:2,
    }
  },
  methods:{
    getFirst(){
      console.log(this.first)
    },
    getSecond(){
      console.log(this.second)
    }
  },
}

子组件

<template>
  <div> 
     // 1
    <h2>{{first}}</h2> 
  </div>
</template>


export default {
  props:{
    first:{
      type:Number,
      default:0
    }
  },
  created(){
    console.log(this.$attrs,this.$listeners)
     // {second:2} {getSecond:fn}
    this.$listeners.getSecond() // 2
  }
};


1.4 provide和inject

相互配合使用,缺一不可
祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。如果你熟悉 React,这与 React 的上下文特性很相似。

祖先组件

<template>
  <div class="home">
    <Son></Son>
  </div>
</template>
export default {
  components:{Son},
  provide:{
    house:'房子',
    car:'车',
    money:'钱'
  }
};

子孙组件

<template>
  <div>

  </div>
</template>

<script>
export default {
  inject:{
    house:{
      default:'没房'
    },
    car:{
      default:'没车'
    },
    money:{
      default:'没钱'
    }
  },
  created(){
    console.log(this.house,this.car,this.money)
    //没房,没车,没钱
  }
};
</script>


1.5 EventBus

声明一个全局Vue实例变量EventBus,把所有的通信数据,事件监听都存储到这个变量上,这样就到达在组件间实现数据共享,有点类似Vuex。但是这种方式只适合极小的项目,复杂的项目还是推荐Vuex。

父组件

<template>
  <div class="home">
    <EventBus></EventBus>
  </div>
</template>
Vue.prototype.EventBus = new Vue()
export default {
  components:{EventBus},
  created(){
    this.EventBus.message = '事件总线';
    this.EventBus.$on('received',function(params){
      console.log(params) //子组件
    })
    this.$nextTick(()=>{
      console.log(this.EventBus.child) // child
    })
  },
};

子组件

export default {
  created(){
    console.log(this.EventBus.message) // 事件总线
    this.EventBus.$emit('received','子组件')
    this.EventBus.child = 'child'
  }
};


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值