vue中各种组件之间如何通信?

首先介绍下父子组件生命周期执行顺序
加载渲染:

父beforeCreate —> 父created —> 父beforeMount —> 子beforeCreate —> 子created —> 子beforeMount —> 子mounted —> 父mounted

更新数据

父beforeUpdate —> 子beforeUpdate —> 子updated —> 父updated

销毁:

父beforeDestroy —> 子beforeDestroy —> 子destroyed —> 父destroyed

其次组件是 vue.js最强大的功能之一,而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互引用。一般来说,组件可以有以下几种关系:
在这里插入图片描述
如上图所示,A 和 B、B 和 C、B 和 D 都是父子关系,C 和 D 是兄弟关系,A 和 C 是隔代关系,A 和 D 是隔代关系。

针对不同的使用场景,他们之间如何通信呢?

1.父子组件通信

父传子 v-bind 子接收父 props
子传父 $emit 父接收子 on
父调用子 $refs 子调用父 $parent

//父组件
<template>
  <div>
    <!-- 传递动态属性给子组件(title),短横线分割命名 -->
    <header-child ref="child" :title="title" @getMessage="showMessage" :getList="getList"></header-child>
    <button @click="getList">获取子组件的数据和方法1</button>
    <button @click="showInfo(1,'男','小张')">获取子组件的数据和方法2</button>
  </div>
</template>
<script>
import HeaderChild from "./HeaderChild.vue";
export default {
  components: {
    "header-child": HeaderChild,
  },
  data() {
    return {
      title: "我是父组件的数据",
      message: "",
    };
  },
  methods: {
    getList() {
      console.log(this.$refs.child.name);
    },
    run() {
      console.log("我是父组件里面的方法");
    },
    showMessage(value) {
      this.message = value;
      console.log(this.message);
    },
    //通过ref调用子组件的方法传值
    showInfo(id, type, name) {
      this.$refs.child.getData(id, type, name);
    },
  },
};
//子组件
<template>
  <div>
    <button @click="getParent()">获取父组件的数据和方法</button>
    <span>{{ getTitle }}</span>
  </div>
</template>
<script>
export default {
  //props是单向绑定的,即只能父组件向子组件传递
  props: {
  	title:{
    	type:String,
    	default:""
  	},
  	//传递方法给父组件
  	getList: {
    	type: Function,
    	default: null,
  	},
  },
  data() {
    return {
      name: "我是子组件里面的数据",
    };
  },
  methods: {
    getParent() {
      console.log(this.$parent.title);
      this.$parent.run();
      this.$emit("getMessage", "我通过emit方法传值给父组件");
      this.getList()
    },
    getData(id, type, name) {
      console.log(id, type, name);
      this.id = id;
      this.type = type;
      this.name = name;
    },
  },
};
</script>

1.1 v-model如何实现父子组件之间通信?

<!--父组件-->
<template>
   <div>
     <child v-model="value"></child>
     <span>{{ value }}</span>
   </div>
</template>
<!--子组件-->
<template>
  <div>
    <input type="text" :myValue="value" @input="inputChange" />
  </div>
</template>
<script>
//对于input事件, :myValue = 'value'也可以不写
export default {
  data() {
    return {};
  },
  props: ["value"],
  model: {
    prop: 'myValue',
    event: 'input'      //emit事件的名称,可以随便取,但下面emit事件的名字要对得上
  },
  methods: {
    inputChange(e) {
      //对于input事件,emit时的名称对应model中event的事件名
      this.$emit("input", e.target.value);
    },
  },
};
</script>

它的原理是
1.展示:父组件中的v-model,子组件接收一个props值value,将它展示到子组件的input上。
2.改变:当子组件自身发生改变时,触发自身的input方法,然后触发父组件的事件方法,改变父组件的value,进而改变接收的props,实现自身展示的改变。

例子中使用了model,官网是这样说的,实际上是为了单选框,复选框按钮等情况的时候,他们的值并不是value,而是checked,这种情况下,就需要写这个。例如:

model: {
  prop: 'checked',
  event: 'change'
},

1.2 子组件如何修改父组件中的props?

对于传递过来的值是引用类型是可以直接修改的,但对于基本数据类型是不能修改的,此时如果想修改就需要使用sync,支持2.3版本级以上。

父组件引用

<icon-tab :activeIndex.sync="activeIndex"></icon-tab>

子组件修改

handleClick(index) {
  this.$emit("update:activeIndex", index);
},

2.兄弟组件通信

2.1 Event Bus

//main.js
import Bus from './utils/bus'
Vue.prototype.$bus = Bus
//bus.js
import Vue from 'vue'
const Bus = new Vue()
export default Bus

使用时接收方和发送方的名字要一致

//发送方
this.$bus.$emit("showModal",data);
//接收方
created() {    
  this.$bus.$on("showModal",(value) => {
    cosnole.log(value)
  }
}
//销毁
beforeDestroy(){
  this.$bus.off("showModal")
}

2.2 vuex

vuex的使用

3.跨级组件通信

3.1 Event Bus

3.2 vuex

3.3 provide和inject

// 父级组件提供 'foo'
var Provider = {
  provide: {
    foo: 'bar'
  },
}

// 子组件注入 'foo'
var Child = {
  inject: ['foo'],
  created () {
    console.log(this.foo) // => "bar"
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值