常用的通讯方式有如下方式
- props
- 自定义事件 $emits $on
- provide/inject
- $refs | $parent | $children | defineExpose()
- $attrs 祖孙传值
- vuex | pinia
1、父子组件之间使用 props 传参
父组件向子组件传递参数,参数可以是Object、Object[]、Array、String、Number、Boolean、Function
等多种数据类型的参数。
如:通过reactive
创建一个person
响应式对象,在子组件中通过 personSon
对象接收数据;
父组件:
<template>
<div class="myComponents">
<!-- 组件之间传参 -->
<MyComParamsSon
:personSon="person"
:name="name"
@changeNameSon="changeName"
></MyComParamsSon>
</div>
</template>
<script setup>
import MyComParamsSon from './myComParamsSon.vue';
import {
ref, reactive } from 'vue';
let name = ref('Andy')
let person = reactive({
name: 'Andy',
age: 18
})
const changeName = (data) => {
person.name = data
}
</script>
子组件:
子组件中接受参数,建议vue3 中直接使用setup 语法糖下的,difineProps
宏函数;
注意:一定要声明接受数据的数据类型,避免传入的数据类型不是子组件想要的,从而导致子组件报错;
如:
difineProps 不用引入,可以直接在setup 语法糖中使用;不建议使用 setup() {return}
函数处理;
二次使用 difineProps
中的属性或对象时,需要使用toRefs()
或者 computed()
二次处理,具体如下代码:
const props = defineProps({
name: {
type: String,
default: '未知'
},
personSon: {
type: Object,
default: () => ({
})
}
})
或者ts写法
// const propsTs = defineProps<{
// name: string,
// personSon: {
// name: string,
// age: number
// }
// }>()
具体代码如下:
<template>
<div class="son-page">
This is a child page.
<br>
name: {
{
name }}
<br>
personSon-name: {
{
personSon.name }}
<br>
personSon-age: {
{
personSon.age }}
<br>
newPerson: {
{
newPerson.name}}
<br>
<el-button type="primary" @click="handleChangeName">change name</el-button>
</div>
</template>
<script setup lang="ts">
import {
ref, reactive, watch, toRefs, computed} from 'vue'
// 建议在setup 中直接使用defineProps 和 defineEmits;
//
// const props = defineProps(['name', 'person']) // 不建议使用这种,这种没有进行类型声明,传入时会导致未知问题
// 推荐使用js 中
const props = defineProps({
name: