十一. 父子组件传参

主要通过 defineProps,defineEmits, defineExpose 这三个内置对象

1. defineProps,defineEmits 的用法

父组件:

1
<menu @on-click="getList" :data="list" title="标题" />

子组件

1
2
// 父传子 type Props = { title: string, data: number[] } defineProps
<Props>() // 子传父 const emit = defineEmits(['on-click']) const handleClick = () => { emit('on-click', list) }</Props>

defineEmits 同时定义多个 emit

1
const emit = defineEmits(['on-click1','on-click2'])

2. defineExpose 的用法

在子组件通过 defineExpose 派发数据,能够在父组件接收到

1
2
const list = reactive
<number[]>([1,2,3]) defineExpose({ list })</number[]>

注意:props 可以设置是否必传,和定义默认值,使用方法如下

1
2
type Props = { title?: string, data: number[] } withDefaults(defineProps
<Props>(), { title: '默认标题', data: () => [1, 2] })</Props>

defineExpose 的具体使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<template>
<div>
<div>父组件</div>
<detail ref="sonRef"></detail>
<el-button @click="getSonMessage">获取子组件数据</el-button>
<div>{{ message }}</div>
<div v-for="item in state.fatherList" :key="item.id">{{ item.name }}</div>
</div>
</template>
<script setup>
import { ref, toRefs, reactive } from 'vue';
import detail from '@/views/role/detail.vue';
let sonRef = ref('sonRef');
let message = ref('');
let state = reactive({
fatherList: [],
});
let getSonMessage = () => {
console.log(sonRef.value.sonInfo, sonRef.value.dataList, '+sonInfo');
state.fatherList = sonRef.value.dataList;
message.value = sonRef.value.message;
sonRef.value.show();
};
</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
26
27
28
29
30
31
32
33
34
35
36
<template>
<div>子组件</div>
<div v-for="item in state.dataList" :key="item.id">{{ item.name }}子组件</div>
</template>
<script setup>
import { defineExpose, onMounted, reactive, ref, toRefs } from 'vue';
import { getuserListApi } from '@/api/user';
let message = ref('简单类型');
let state = reactive({
dataList: [{ id: 1, name: 123 }],
sonInfo: {
name: '子组件',
tip: '对象',
},
});
onMounted(async () => {
let { code, data } = await getuserListApi();
if (code == 0) {
state.dataList = data;
}
});
let show = () => {
console.log('子组件的show方法');
};
let { dataList } = toRefs(state);

defineExpose({
//用state.dataList父组件接收的是初始化的数据,
// 不是从onMounted里面取的数据,但是子组件的datalist是从onMounted拿到的最新数据。
// 把dataList从state里面通过toRefs解构,父组件也可拿到最新的数据
dataList: dataList,
message,
show,
sonInfo: state.sonInfo,
});
</script>