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
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
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
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
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
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
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
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
2
3
4
5
6
7
8
9
10
# 五、eventBus
Vue 3 中移除了 eventBus,但可以借助第三方工具来完成。Vue 官方推荐使用 mitt 或 tiny-emitter。
# 六,vuex/pinia
- 更加推荐使用pinia状态管理
# 七,v-model
- 稍后会重点讲解