Relationship between Vue3 components
实际业务开发过程中,一定会用到组件间通信,如父子组件通信、兄弟组件通信、爷孙组件通信,还有一些全局通信的场景
The relationship between components can be seen in the figure below:
This article mainly explains the communication between parent and child components in detail
Common ways to pass values between parent and child components
父子组件传值是开发过程中使用最多也是必掌握的方式 具体可以分为以下三种:
- 1. props/emits method
- 2. v-model/emits method
- 3.ref/emits method
1. props/emits method
father to son
Introduce the child component in the parent component, and then bind the value that needs to be passed to the child component on the child component
<template>
<Child
title="用户信息"
:index="1"
:uid="userInfo.id"
:to-parent="getChilderVal"
/>
</template>
Subcomponents receive via props,
const props = defineProps<{
index: string
uid: number
}>()
The child component uses the received value
const {
index,uid}=toRefs(props)
child's father
The subcomponent defines emits, and emits are triggered by binding an event to the subcomponent:
const emits = defineEmits(['toParent'])
const selectChange = (id: number) => {
emits('toParent', id)
}
The parent component receives via getChilderVal:
<Child
title="用户信息"
:index="1"
:uid="userInfo.id"
:to-parent="getChilderVal"
/>
const getChilderVal=(id:number)=>{
console.log(id)
}
2. v-model/emits method
Compared with props / emits, this method is simpler:
- In Father.vue, pass the value to Child.vue through v-model
- Child.vue notifies Father.vue of data updates through the emits set by itself
father to son
The parent component directly passes the value to the child component through v-model:
<template>
<Child
v-model:user-name="userInfo.name"
/>
</template>
Subcomponents are similarly received through props:
const props = defineProps<{
userName: string
}>()
child's father
Subcomponents can pass the "update" field:
const emits = defineEmits(['update:userName'])
emits('update:userName')
3. ref/emits method
ref 是可以用在 DOM 元素与子组件上面,所以,父组件也可以直接通过对子组件绑定 ref 属性,然后通过 ref 变量去操作子组件的数据或者调用里面的方法
father to son
For example, if you import a Child.vue as a subcomponent, you need to bind the subcomponent tag at the template with ref:
subcomponent:
<template>
<Child ref="child" />
</template>
Parent component:
define a ref variable for the child component
const child = ref<HTMLElement>(null);
// 执行子组件里面的ajax函数
child.value.getList();
// 打开子组件里面的弹窗
child.value.isShowDialog = true;
child's father
If the child component wants to actively communicate with the parent component, it also needs to use emit, so I won’t repeat the explanation here
Parent and child component methods call each other
Child component calls method in parent component
parent component:
<template>
<div>
<child :parent-handler="parentHandler" />
</div>
</template>
<script lang="ts" setup>
import child from "@/components/child";
const parentHandler=()=>{
console.log("这是父组件的方法");
}
</script>
Subassembly:
<template>
<div>
<button @click="handler">这是子组件的按钮</button>
</div>
</template>
<script lang="ts" setup>
const props = defineProps<{
parentHandler: Function
}>()
};
//使用
props.parentHandler()
</script>
Parent component calls method in child component
parent component:
<template>
<div class="mt-5">
<Son ref="RefChilde"></Son>
<div class="btn btn-primary my-2" @click="fnCallChild">
点我调用Son组件里的方法
</div>
</div>
</template>
<script lang="ts" setup>
import Son from "../components/Son.vue";
const RefChilde = ref(); //RefChilde 要和Son组件上的class名相同
const fnCallChild = () => {
RefChilde.value.sonFn(); //sonFn是子组件里的方法
};
</script>
Subassembly:
<template>
<div>
<h1>{
{
conts }}</h1>
</div>
</template>
<script lang="ts" setup>
const conts = ref("我是子组件");
const sonFn = () => {
conts.value = "我被父组件里调用了子组件的方法修改了数据";
};
</script>