vue 组件通讯总结

Props $emit 方式

父子传参最常用的方式就是使用props,$emit

1. 父传子

子组件从父组件接受参数通过props,并且可以规定类型,默认值等
总结

1.父组件中 v-bind:parentToOne="parentMsg" ,
一般parentToOne 与 parentMsg 名称相同即可
即:v-bind:parentMsg="parentMsg" 下面props接收也改为parentMsg,这里为了阐明关系
2.子组件中Props接收  parentToOne

父组件

	<template>
	  <div class="parent">
	    <SubOne :parentToOne="parentMsg"/>
	  </div>
	</template>
	<script>
	import SubOne from './components/SubOne'
	export default {
	  name:"parent",
	  data(){
	    return {
	      parentMsg:'parent',
	    }
	  },
	  components:{SubOne},
	}
	</script>

子组件

<template>
    <h6>来自父组件的参数parentMsg:{{parentToOne}}</h6>
</template>
<script>
	export default {
	  name: "SubOne",
	  props: {
	  //规定类型,默认值
	    parentToOne: {
	      type: String,
	      default: "xxx",
	    },
	  }
	};
</script>

2. 父传子,且子组件修改props传递参数,通过sync 修饰符

总结

1.父组件中在给传递给子组件的参数添加sync修饰符
2.子组件中通过$emit('update: propName',value)

父组件

<h3>I am父组件</h3>
<SubTwo :parentMsg.sync="parentMsg"/>

子组件

	<template>
	   <h6>
	     修改父数据:<input type="text" @input="msgChange">
	   </h6>
	</template>
	<script>
	export default {
	  name: "SubTwo",
	  //接受参数
	  props: {
	    parentMsg: {
	      type: String,
	      default: "xxx",
	    },
	  },
	  methods:{
	    msgChange:function($event){
	    //在子组件方法里 通过$emit修改
	      this.$emit('update:parentMsg',$event.target.value)
	    }
	  },
	};
	</script>

3. 子传父

总结

1.父组件里 给子组件添加v-on 监听并绑定父组件方法接收参数
2.子组件里面 $emit通过subThree 触发reserveSubMsg

父组件

<template>
  <div class="parent">
    <h3>I am 父组件</h3>
    <h6>接收subThree的参数 subMsg:{{subMsg}}</h6>
    <SubThree v-on:subThree="reserveSubMsg"/>
  </div>
</template>
<script>
import SubThree from './components/SubThree'
export default {
  name:"parent",
  data(){
    return {
      subMsg:''
    }
  },
  components:{
   SubThree
  },
  methods:{
    reserveSubMsg(value){
      this.subMsg = value
    }
  }
}
</script>

子组件

<template>
  <div class="sub">
      传递父数据:<input type="text" v-model="value" @input="msgChange">
  </div>
</template>
<script>
export default {
  name: "SubThree",
  data() {
    return {
      value:''
    };
  },
  methods: {
    msgChange(){
      this.$emit('subThree',this.value)
    }
  },
};
</script>

provide inject 方式

父子之间传递参数也是有缺点的,比如子组件嵌套很深的情况下,逐层传递会很麻烦,
provide-inject方式可以很方便的解决这个问题
总结

这种方式比较像发布订阅
1.在顶层组件中,通过provide 发布变量(与data同级)
2.顶层组件的子组件中都可以通过inject 接收到变量,可以直接通过this访问

顶级组件

  provide() {
    return {
      topFloorMsg: "come from top",
    };
  },

子组件

//省略部分代码 完整代码见下
  <h6>来自top组件的参数 topFloorMsg: {{topFloorMsg}}</h6>
  inject:['topFloorMsg'],

bus 非组件之间传值

总结

思路:实例化一个vue实例,利用它身上的$emit $on 
1. 生成实例,来做为中间传达的工具
2. 在任意组件 $emit 发布变量
3. 在任意组件 $on 订阅监听变量

//bus.js
import Vue from 'vue'
export default new Vue()

BusA

  // 引入公共的bus,来做为中间传达的工具
  import Bus from '@/bus.js'
  //方法中触发
   methods: {
    usHandle(){
      Bus.$emit('busMsg','come from bus')
    }
  },

BusB

 <h6>来自Bud事件总线的 busMsg: {{ value }}</h6>
  mounted(){
    var vm = this;
    // 用$on事件来接收参数
    Bus.$on("busMsg", (data) => {
      console.log(data);
      vm.value = data;
    });
  },

完整代码

父组件

<template>
  <div class="parent">
    <div class="item">
      <h3>父子传参 props $emit</h3>
      <h6>父组件参数 parentMsg:{{ parentMsg }}</h6>
      <h6>接收subThree的参数 subMsg:{{ subMsg }}</h6>
      <SubOne :parentToOne="parentMsg" />
      <SubTwo :parentMsg.sync="parentMsg" />
      <SubThree v-on:subThree="reserveSubMsg" />
    </div>
    <div class="item">
      <h3>Provide - Inject方式</h3>
      <Son />
    </div>
    <div class="item">
      <h3>Bus方式</h3>
      <button @click="busHandle">传递参数</button>
      <BusA/>
    </div>
  </div>
</template>
<script>
import SubOne from "./components/SubOne";
import SubTwo from "./components/SubTwo";
import SubThree from "./components/SubThree";
import Son from "./components/Son";
  // 引入公共的bug,来做为中间传达的工具
  import Bus from '@/bus.js'
import BusA from "./components/BusA";
  
export default {
  name: "parent",
  data() {
    return {
      parentMsg: "parent",
      subMsg: "",
    };
  },
  provide() {
    return {
      topFloorMsg: "come from top",
    };
  },
  components: {
    SubOne,
    SubTwo,
    SubThree,
    Son,BusA
  },
  methods: {
    reserveSubMsg(value) {
      this.subMsg = value;
    },
    busHandle(){
      Bus.$emit('busMsg','come from bus')
    }
  },
};
</script>
<style lang="scss" scoped>
.parent {
  padding: 20px;
  background: #ffffff;
  border: 1px dashed pink;
  display: flex;
  justify-content: space-around;
  .item{
    width: 33%;
  }
}
</style>

SubOne

<template>
  <div class="sub">
    <h3>I am subOne 子组件 我专门接受父组件参数</h3>
    <h6>来自父组件的参数parentMsg:{{parentToOne}}</h6>
  </div>
</template>
<script>
export default {
  name: "SubOne",
  props: {
    parentToOne: {
      type: String,
      default: "xxx",
    },
  }
};
</script>
<style lang="scss" scoped>
.sub{
  border: 1px dashed #333332;
  background: lightblue;
}
</style>

SubTwo

<template>
  <div class="sub">
    <h3>I am subTwo 子组件 我接受并修改父组件参数</h3>
    <h6>来自父组件的参数parentMsg:{{parentMsg}}</h6>
    <h6>
      修改父数据:<input type="text" @input="msgChange">
    </h6>
  </div>
</template>
<script>
export default {
  name: "SubTwo",
  props: {
    parentMsg: {
      type: String,
      default: "xxx",
    },
  },
  methods:{
    msgChange:function($event){
      console.log($event.target.value);
      this.$emit('update:parentMsg',$event.target.value)
    }
  },
};
</script>
<style lang="scss" scoped>
.sub{
  margin-top: 20px;
  border: 1px dashed #333332;
  background: lightblue;
}
</style>

SubThree

<template>
  <div class="sub">
    <h3>
      I am subThree 子组件 我给父组件传递参数
    </h3>
      传递父数据:<input type="text" v-model="value" @input="msgChange">
  </div>
</template>
<script>
export default {
  name: "SubThree",
  data() {
    return {
      value:''
    };
  },
  components: {},
  methods: {
    msgChange($event){
      console.log($event.target.value);
      this.$emit('subThree',this.value)
    }
  },
};
</script>
<style lang="scss" scoped>
.sub{
  border: 1px dashed #333332;
  background: lightblue;
}
</style>

son

<template>
  <div class="sub">
    <h3>
      I am Son 子组件 
    </h3>
    <h6>来自top组件的参数 topFloorMsg: {{topFloorMsg}}</h6>
    <!-- <Grandson/> -->
  </div>
</template>
<script>
// import Grandson from './Grandson'
export default {
  name: "Son",
  inject:['topFloorMsg'],
  components:{
    // Grandson
  }
};
</script>
<style lang="scss" scoped>
.sub{
  border: 1px dashed #333332;
  background: lightblue;
}
</style>

BusA.vue

<template>
  <div class="sub">
    <h3>
      I am BusA 子组件
    </h3>
    <h6>来自Bud事件总线的 busMsg: {{ value }}</h6>
  </div>
</template>
<script>
import Bus from "@/bus.js";
export default {
  name: "BusA",
  data(){
    return{
      value:''
    }
  },
  mounted(){
    var vm = this;
    
    // 用$on事件来接收参数
    Bus.$on("busMsg", (data) => {
      console.log(data);
      vm.value = data;
    });
  },
};
</script>
<style lang="scss" scoped>
.sub {
  border: 1px dashed #333332;
  background: lightblue;
}
</style>

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值