vue 组件通信(全)

props / $emit

父传子用 props
子组件用$emit提交事件

ref / refs

为子组件绑定 ref,父组件通过调用refs调用子组件的方法或属性
父组件

  <ChildOne ref="child" :msg="msg" @change="change" />
this.childMesg = this.$refs.child.childMesg;

provide/inject

父组件通过provide提供值
子组件通过inject获取值
provide组件

<template>
  <div>
    <h3>provide</h3>
    <p></p>
    <Inject />
  </div>
</template>
<script>
import Inject from "./inject";
export default {
  name: "procide",
  components: { Inject },
  date() {
    return {
      // msg: "provide content",
    };
  },
  provide: {
    msg: "provide content",
  },
};
</script>

inject组件

<template>
 <div>
   <h3>inject</h3>
   <p>{{ msg }}</p>
 </div>
</template>
<script>
export default {
 name: "inject",
 inject: ["msg"],
};
</script>

$children / $parent

父组件通过$children,拿到子组件实例
子组件通过$parent,拿到父组件实例
parent组件

<template>
  <div class="box">
    <div class="box-item">
      <p>parent 内容初始化</p>
      <button @click="getChild1">获取子组件内容过$children</button>
      <p>通过$children{{ childMesg1 }}</p>
    </div>
    <div class="box-item">
      <ChildOne ref="child" />
    </div>
  </div>
</template>
<script>
import ChildOne from "./child";
export default {
  name: "parentone",
  components: { ChildOne },
  data() {
    return {
      msg: "我是parent传递给child的通过props",
      childMesg: "",
      childMesg1: "",
      msg1: "父组件内容",
    };
  },
  methods: {
    getChild1() {
      this.childMesg1 = this.$children[0].childMesg;
    },
  },
};
</script>
<style scoped>
.box {
  padding: 20px;
  border: 1px solid rosybrown;
}
.box-item {
  padding: 10px;
  margin-bottom: 20px;
  border: 1px solid #dddddd;
}
</style>

child组件

<template>
 <div>
   <h3>我是子组件</h3>
   <p>{{ msg1 }}</p>
   <button @click="change1">通过$perent获取父组件的内容</button>
 </div>
</template>
<script>
export default {
 name: "childone",
 data() {
   return {
     childMesg: "我是子组件的内容",
     msg1: "",
   };
 },
 methods: {
   change1() {
     this.msg1 = this.$parent.msg1;
   },
 },
};
</script>

eventBus

基本兼容所有的情况,但是管理不便
eventBus.js

import Vue from "vue";
const EventBus = new Vue();
export default EventBus;

父组件

<template>
  <div>
    <h3>parent</h3>
    <ChildA />
    <ChildB />
  </div>
</template>
<script>
import ChildA from "./a";
import ChildB from "./b";
export default {
  name: "parent",
  components: { ChildA, ChildB },
};
</script>
<style scoped>
</style>
兄弟a
<template>
  <div class="box">
    <h3>兄弟组件a</h3>
    <h4>{{ num }}</h4>
    <button @click="changeb">chang兄弟b</button>
  </div>
</template>
<script>
import EventBus from "./bus";
export default {
  name: "child1",
  data() {
    return {
      num: 10,
    };
  },
  mounted() {
    EventBus.$on("change-a", (data) => {
      this.num = data.num;
    });
  },
  methods: {
    changeb() {
      EventBus.$emit("change-b", {
        num: (Math.random() * 100).toFixed(2),
      });
    },
  },
};
</script>
<style scoped>
.box {
  padding: 10px;
  margin: 10px;
  border: 1px solid #231;
}
</style>

兄弟b

<template>
  <div class="box">
    <h3>兄弟组件b</h3>
    <h4>{{ num }}</h4>
    <button @click="changea">chang兄弟a</button>
  </div>
</template>
<script>
import EventBus from "./bus";
export default {
  name: "child1",
  data() {
    return {
      num: 10,
    };
  },
  mounted() {
    EventBus.$on("change-b", (data) => {
      this.num = data.num;
    });
  },
  methods: {
    changea() {
      EventBus.$emit("change-a", {
        num: (Math.random() * 100).toFixed(2),
      });
    },
  },
};
</script>
<style scoped>
.box {
  padding: 10px;
  margin: 10px;
  border: 1px solid #231;
}
</style>

$attrs/ $listeners 针对跨级通信

对于多层嵌套比较方便,每层都去绑定事件和属性,
parent组件

<template>
  <div class="box">
    <div class="box-item">
      <p>parent 内容初始化</p>
      <p>{{ geandsonmsg }}</p>
    </div>
    <div class="box-item">
      <ChildTwo ref="child" :msg="msg" @change="change" />
    </div>
  </div>
</template>
<script>
import ChildTwo from "./child";
export default {
  name: "parenttwo",
  components: { ChildTwo },
  data() {
    return {
      msg: "我是parent传递给grand-son的",
      geandsonmsg: "",
    };
  },
  methods: {
    getChild() {
      this.childMesg = this.$refs.child.childMesg;
    },
    change(msg) {
      this.geandsonmsg = msg;
    },
  },
};
</script>
<style scoped>
.box {
  padding: 20px;
  border: 1px solid rosybrown;
}
.box-item {
  padding: 10px;
  margin-bottom: 20px;
  border: 1px solid #dddddd;
}
</style>

子组件

<template>
  <div>
    <h3>我是子组件</h3>
    <GrandSon v-bind="$attrs" v-on="$listeners" />
  </div>
</template>
<script>
import GrandSon from "./grandson";
export default {
  name: "childtwo",
  components: { GrandSon },
  data() {
    return {};
  },
};
</script>

孙子组件

<template>
  <div class="div">
    <h3>我是孙子组件</h3>
    <p>{{ msg }}</p>
    <button @click="change">change parent</button>
  </div>
</template>
<script>
export default {
  name: "grand-son",
  props: {
    msg: String,
  },
  data() {
    return {
      grandsonmsg: "我是孙子组件的内容",
    };
  },
  methods: {
    change() {
      this.$emit("change", this.grandsonmsg);
    },
  },
};
</script>
<style scoped>
.div {
  padding: 10px;
  margin-bottom: 20px;
  border: 1px solid #18192c;
}
</style>

所有例子的代码

例子代码:例子代码

原文地址:https://www.cnblogs.com/heihei-haha/p/14554668.html