03-Vue3组件通信

7/24/2022

# 一、props

props主要用于父组件向子组件通信。在父组件中通过用 :msg="msg" 绑定需要传给子组件的属性值,然后再在子组件中用 props 接收该属性值。

父组件App.vue:

<template><Demo :msg1="msg1" :msg2="msg2" /></template>

<script setup>
import Demo from "./components/Demo.vue";

import { ref, reactive } from "vue";
//基础类型传值
const msg1 = ref("码路");
// 复杂类型(数组或对象)传值
const msg2 = reactive(["漫漫", "前端"]);
</script>
1
2
3
4
5
6
7
8
9
10
11

子组件Demo.vue:

<template>
  <h1>父组件传给子组件的值</h1>
  <h2 v-text="msg1"></h2>
  <h2 v-text="msg2"></h2>
</template>

<script setup>
import { defineProps } from "vue";
// 这里不需要在从vue中引入defineProps,直接用
defineProps({
  // 第一种写法
  msg1: String,
  // 第二种写法
  msg2: {
    type: String,
    default: "",
  },
});
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 二、$emit

  • $emit 也就是通过自定义事件传值,主要用于子组件向父组件通信。
  • 在子组件的点击事件中,通过触发父组件中的自定义事件,把想传给父组件的信息以参数的形式带过去,父组件便可以拿到子组件传过来的参数值。

父组件App.vue:

<template><Demo @myClick="onMyClick" /></template>

<script setup>
import Demo from "./components/Demo.vue";

// 父组件接受到子组件传过来的值
const onMyClick = (msg) => {
  console.log(msg);
};
</script>
1
2
3
4
5
6
7
8
9
10

子组件Demo.vue:

<template>
  <h1>$emit</h1>
  <button @click="emit('myClick', '1000万')">按钮</button>
</template>

<script setup>
import { defineEmits } from "vue";
const emit = defineEmits("myClick");
</script>

<!-- 或如下: -->

<template>
  <h1>$emit</h1>
  <button @click="handleClick">按钮</button>
</template>

<script setup>
import { defineEmits } from "vue";
const emit = defineEmits("myClick");

const handleClick = () => {
  emit("myClick", "1000万");
};
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

# 三、ref

有时候想访问refs绑定的组件的属性或者方法,我们会使用refs绑定的组件的属性或者方法,我们会使用refs绑定的组件的属性或者方法,我们会使用refs。但是Vue3不同于Vue2,在 Vue3的setup中我们是无法访问到this的,所以我们需要借助一个方法,那就是getCurrentInstance,该方法返回了当前的实例对象。

父组件App.vue:

<template>
  <Demo ref="childRef" />
  <button @click="show">show child message</button>
</template>

<script setup>
import Demo from "./components/Demo.vue";

import { ref } from "vue";

const childRef = ref(null);

let show = () => {
  let child = childRef.value;
  console.log(child.msg);
  child.alertMessage();
};
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

子组件Demo.vue:

<template>
  <h1>Ref</h1>
</template>

<script setup>
import { ref, defineExpose } from "vue";

let msg = ref("666").value;

let alertMessage = () => {
  alert(msg);
};

defineExpose({
  msg,
  alertMessage,
});
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

注意: 通过组合语法糖的写法,其组件是默认关闭的,也就是说如果是通过$refs或者$parents来访问子组件中定义的值是拿不到的,必须通过defineExpose向外暴露你想获取的值才行

# 四、provide/inject

provide与inject 主要为父组件向子组件或多级嵌套的子组件通信。

  • provide:在父组件中可以通过 provide 提供需要向后代组件传送的信息。
  • inject:从父组件到该组件无论嵌套多少层都可以直接用 inject 拿到父组件传送的信息。

父组件App.vue:

<template>
  <Demo ref="childRef" />
</template>

<script setup>
import Demo from "./components/Demo.vue";

import { provide } from "vue";
// 父组件通过 provide 提供给子组件的信息
provide("car", "奔驰");
</script>
1
2
3
4
5
6
7
8
9
10
11

子组件Demo.vue:

<template>
  <h1>provide / inject</h1>
</template>

<script setup>
import { inject } from "vue";
// 后代组件通过 inject 可以直接拿到父组件提供的信息
const car = inject("car");
console.log(car);
</script>
1
2
3
4
5
6
7
8
9
10

# 五、eventBus

Vue 3 中移除了 eventBus,但可以借助第三方工具来完成。Vue 官方推荐使用 mitt 或 tiny-emitter。

# 六,vuex/pinia

  • 更加推荐使用pinia状态管理

# 七,v-model

  • 稍后会重点讲解
Last Updated: 12/25/2022, 10:02:14 PM