Vue 组件之间的通信

99 阅读1分钟

1. $emit props

App.vue

<template>
  <div id="app">
    <child-a :msg="msg" @handler="handler"></child-a>
  </div>
</template>

<script>
import ChildA from "./components/ChildA.vue";
export default {
  name: "App",
  components: {
    ChildA
  },
  data: function () {
    return {
      msg: "我是父组件派来的小妖精。"
    };
  },
  methods: {
    handler: function () {
      this.msg = "子改父";
    }
  },
};
</script>

ChildA.vue

<template>
  <div>
    <h1 @click="change">{{ msg }}</h1>
  </div>
</template>

<script>
export default {
  name: "ChildA",
  props: ["msg"],
  methods: {
    change: function () {
      this.$emit("handler");
    }
  }
};
</script>

2. provide inject 父传子/传孙

provide的里面的数据是可以传递给子级使用,数据是向下传递的。
App.vue

<script>
import ChildA from "@/components/ChildA.vue";
export default {
  name: "App",
  components: {
    ChildA
  },
  provide: function () {
    return {
      sunMsg: () => this.yeye,
      mm: "我爱你哦宝贝",
    };
  },
  mounted() {
    /* 模拟后台返回的数据 */
    setTimeout(() => {
      this.yeye = "我爱你哦 可爱的小孙子";
    }, 500);
  },
  data: function () {
    return {
      yeye: ""
    }
  }
};
</script>

孙子组件

<template>
  <div>
      <h1>{{sunMsg()}}</h1>
      <h1>{{mm}}</h1>
  </div>
</template>

<script>
export default {
    name:"SunZi",
    /* 孙子可以使用inject获取爷爷传过来的sunMsg数据 */
    inject:['sunMsg','mm']
}
</script>

3. $children $parent

通过$parent$children就可以访问组件的实例。
$children 的值是数组,而$parent是个对象。
App.vue

<template>
  <div id="app">
    <img alt="whale" src="./assets/whale.webp" @click="fn" title="点我变">
    <child-a></child-a>
  </div>
</template>

<script>
import ChildA from "./components/ChildA.vue";

export default {
  name: "App",
  components: {
    ChildA
  },
  data: function () {
    return {
      str: "我是父组件不想费事传的一句话。",
    };
  },
  methods: {
    changeStr: function () {
      this.str = "我变了!";
    },
    fn: function () {
      this.$children[0].changeStr();
    },
  },
};
</script>

ChildA.vue

<template>
  <div>
    <h2>{{ $parent.str }}</h2>
    <h1 style="color: orange">{{ childStr }}</h1>
  </div>
</template>

<script>
export default {
  name: "ChildA",
  props: ["msg"],
  created() {
    this.$parent.changeStr();
  },
  data: function () {
    return {
      childStr: "我是子组件data里的一句话。",
    };
  },
  methods: {
    changeStr: function () {
      this.childStr = "我是子组件data里的,我变了!";
    },
  },
};
</script>

4. $bus 事件总线

(1)在构造函数Vue的原型身上添加一个$bus属性,属性的值是Vue的实例化对象。
(2)在需要传值的组件上,添加自定义事件。
(3)在需要接收值的组件上,使用$on方法先监听其他组件发送过来的自定义事件,用回调函数接收值。
事件总线传值不局限于兄弟组件,父子组件也可传值。
总的特征:先监听自定义事件,再发送自定义事件。
❗频繁使用,会浪费性能。

兄弟组件传值例子:

_{{LEWP{OHCRH0D2E6T%M.png

5. $refs 获取子组件的属性与值

如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例,可以通过实例直接调用组件的方法或访问数据。
App.vue

<template>
  <div id="app">
    <h3 @click="change" ref="native">我是原生DOM,点我改变</h3>
    <KidA ref="kida"></KidA>
  </div>
</template>

<script>
import KidA from "./components/KidA.vue";
export default {
  name: "App",
  components: {
    KidA
  },
  mounted(){
    console.log(this.$refs.kida);
  },
  methods: {
    change() {
      this.$refs.native.style.color = "orange";
      this.$refs.native.innerHTML = "我变了!";
    }
  }
};
</script>

6. .sync语法糖

利用.sync语法糖实现父子通信

image.png