Vue2.x:如何实现组件间的通信

前言

props实现父传子

codepen: 我的在线实例

  1. 本文介绍子组件如何通过props获得父组件data。
  2. 接着把父组件的消息分别放入子组件的data和computed,发现了不同的结果;
  3. 放入子组件的computed,也即思路①,是抽离子组件的正解。
  4. 子组件应该使用vm.$emit()触发父组件的事件方法,第一个参数代表你选择的事件方法,父组件应拥有对应的自定义v-on指令;第二个参数代表你想要传过去的数据。

纠正:2、3点的描述是有问题的,当时我还没有研究清楚。应为:不同的情况采用不同的策略,无论如何你不应该试图直接修改props:单向数据流。

  • 这个 prop 用来传递一个初始值;这个子组件接下来希望将其作为一个本地的 prop 数据来使用。
  • 这个 prop 以一种原始的值传入且需要进行转换。在这种情况下,最好使用这个 prop 的值来定义一个计算属性。

Vue如何实现组件间的通信

从组件间的关系可以分为4类通信手段:

  1. 父子组件间的通信: 使用属性传递(props),使用v-on通过事件通信。

    • v-on常运用自定义事件的写法,父组件形如<train-city @showCityName="updateCity" :sendData="toCity"></train-city>
    • 子组件<button @click='select(大连)'>点击此处将‘大连’发射给父组件</button>
    • 子组件在事件方法select中使用vm.$emit("showCityName",data)达成通信(子传父)
  2. 爷孙组件通信:使用provide, inject

  3. 任意组件间通信:使用eventbus = new Vue()来通信,eventbus.$oneventbus.$emit是主要API

  4. 任意组件间通信:使用Vuex进行通信


父子组件通信

  1. 父组件:通过props传递数据。(传递一个对象。)
    • template中为子组件添加props
    • js中声明自己的data
    • js中声明自己的子组件
//@/component/parent.vue

<template>
  <div id="parent">
    <p>父:</p>
    {{msg}}
    <br>
    {{msg2}}
    <Child :parentMsg="{msg,msg2}"/>
  </div>
</template>
<script>
import Child from "./child.vue";
export default {
  data() {
    return {
      msg: "我是父组件的消息",
      msg2: "诶,我也是",
    };
  },
  components: {
    Child
  },
}
</script>
  1. 子组件
  • 父组件中template怎么给子组件写props, 子组件的js就照着引入。
//@/component/child.vue
<template>
  <div id="child">
    <p>子:</p>
    {{parentMsg.msg}}
    <br>
    {{parentMsg.msg2}}
  </div>
</template>

<script>
export default {
  props: ["parentMsg"],
}
</script>

抽离子组件的思路

步骤A:修改父组件,添加一个修改父组件自己data的methods
步骤B:注释掉子组件的data或者computed

  1. 思路有两种,①存到子组件computed,以及②存到子组件data。
  2. 测试效果比较微妙:
    • 思路①子组件跟着父组件data变化,
    • 思路②则没有跟随变化。
  3. 不明白个中道理。

步骤C:给思路②作延申,给父组件data初始化msg和msg2,发现此延申下,子组件的数据是父组件最原始初始化的内容。

//@/component/parent.vue

<template>
  <div id="parent">
+     <button @click="bind1">我是父组件,要修改自己的data</button>
   <p>父:</p>
    {{msg}}
    <br>
    {{msg2}}
    <Child :parentMsg="{msg,msg2}"/>
  </div>
</template>

<script>
import Child from "./child.vue";
export default {
  data() {
    return {
      msg: "我是父组件的消息",
      msg2: "诶,我也是",
      type: true
    };
  },
  components: {
    Child
  },
+   methods: {
+     bind1() {
+       if (this.type) {
+         this.msg = "我被改变,而子组件不改变";
+         this.type = false;
+       } else {
+         this.msg = "我是父组件的消息";
+         this.type = true;
+       }
+     }
+   }
};
</script>

//@/component/child.vue

<template>
  <div id="child">
    <!-- {{parentMsg.msg}}<br>
    {{parentMsg.msg2}}-->
    <p>子:</p>
    {{msg}}
    <br>
    {{msg2}}
  </div>
</template>

<script>
export default {
  props: ["parentMsg"],
+  data() {
+    return {
+      msg: this.parentMsg.msg,
+      msg2: this.parentMsg.msg2
+    };
+  }
+  // computed: {
+  //   msg() {
+  //     return this.parentMsg.msg;
+  //   },
+  //   msg2() {
+  //     return this.parentMsg.msg2;
+  //   }
+  // }
};
</script>

我的在线实例

总结

  1. 本文介绍子组件如何通过props获得父组件data。
  2. 接着把父组件的消息分别放入子组件的data和computed,发现了不同的结果。
  3. 放入子组件的computed,也即思路①,是抽离子组件的正解。

参考

  1. 岁月如同马匹:vue父子组件之间的通信
  2. vue文档——Props
  3. vue中 关于$emit的用法
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容