Article directory
1. Communication of components
1.1. Communication between parent and child components
1.1.1 Pass value from parent component to child component
Method 1: When the parent component passes a value to the child component, v-on
it is realized by binding properties
// parent.vue
<template>
<div>
父子组件传值
<children :msg="msg" :foo="foo"/>
</div>
</template>
<script setup lang="ts">
import {
ref } from 'vue';
import children from './components/children.vue';
let msg = ref('hello word');
let foo = ref(10);
</script>
<style scoped>
</style>
The child component defineProps
receives the value passed by the parent component.
- Receive the value passed by the parent component in the form of a string
// children.vue
<template>
<div class="wrapper">
这是子组件<br/>
父传子:{
{ props.msg }} {
{ props.foo }}
</div>
</template>
<script setup lang="ts">
let props = defineProps(['msg', 'foo'])
</script>
<style scoped>
</style>
- Use the form of an object to receive the value passed by the parent component
// children.vue
<template>
<div class="wrapper">
这是子组件<br/>
父传子:{
{ props.msg }} {
{ props.foo }}
</div>
</template>
<script setup lang="ts">
let props = defineProps({
msg: String,
foo: Number
})
</script>
<style scoped>
</style>
- Receive the value passed by the parent component in the form of an object (including default values and required parameter settings)
// children.vue
<template>
<div class="wrapper">
这是子组件<br/>
父传子:{
{ props.msg }} {
{ props.foo }}
</div>
</template>
<script setup lang="ts">
let props = defineProps({
msg: {
type: String,
default: '',
required: true // 设置后参数必传
},
foo: {
type: Number,
default: 0
}
})
</script>
<style scoped>
</style>
- Use with TypeScript
// children.vue
<template>
<div class="wrapper">
这是子组件<br/>
父传子:{
{ props.msg }} {
{ props.foo }}
</div>
</template>
<script setup lang="ts">
let props = defineProps<{
msg?: string;
foo: number
}>()
</script>
<style scoped>
</style>
Method 2: The parent component 插槽(slot)
passes parameters to the child component
slot
Pass parameters through tags in subcomponents- Insert the content in the parent component
template
andv-slot
receive the data passed by the slot
<!-- Parent.vue -->
<template>
<Child>
<template #default="{ message }">
{
{ message }}
</template>
</Child>
</template>
<script>
import Child from './Child.vue'
</script>
<!-- Child.vue -->
<template>
<div>
<slot :message="message"></slot>
</div>
</template>
<script setup lang="ts">
import {
ref } from 'vue'
const message = ref('Hello, world!')
</script>
It should be noted that slots can only be used to pass static content. If you need to pass dynamic content, you need to use props or provide/inject to achieve it. In addition, multiple slots can be defined, and different slots can be distinguished through the name attribute.
Method 3: v-model
, the child component can directly modify the value passed by the parent component
In Vue3, v-model
instructions can be used to implement child components to directly modify the value passed by the parent component. Specifically, you can use instructions in the parent component to bind v-model
a variable to one of the child components , and then use a method in the child component to trigger an event named plus the name of the prop, and pass a new value as a parameter. For example:prop
emit
update:
<!-- VmodelParent.vue -->
<template>
<div>
v-model传参:父组件
<VmodelChild v-model:isShow="isShow" />
</div>
</template>
<script setup lang="ts">
import {
ref } from 'vue';
import VmodelChild from './components/VmodelChild.vue';
const isShow = ref(false)
</script>
<style scoped>
</style>
<!-- VmodelChild.vue -->
<template>
<div>
v-model传参:子组件
<button @click="handleClick">点击修改参数</button>
<br />
{
{ props.isShow }}
</div>
</template>
<script setup lang="ts">
import {
defineProps, defineEmits } from 'vue';
const props = defineProps({
isShow: {
type: Boolean,
default: false
}
})
const emit = defineEmits(["update:isShow"])
const handleClick = () => {
emit("update:isShow", !props.isShow)
}
</script>
<style scoped>
</style>
1.1.2. Child components pass values to parent components
The child component passes the value to the parent component by defineEmits
implementing
<template>
<div class="wrapper">
这是子组件<br/>
<button @click="emitToParent">click</button>
</div>
</template>
<script setup lang="ts">
let emit = defineEmits(['event-to-parent'])
let emitToParent = () => {
emit('event-to-parent', '子组件传递给父组件的值')
}
</script>
<style scoped>
</style>
1.2. Communication between sibling components
The eventBus was removed in Vue 3, but it can be done with the help of third-party tools. Vue officially recommends using mitt
or tiny-emitter
.
Example: Take mitt
as an example
1.2.1. Installation
yarn add mitt -S
1.2.2. Registration
- eventBus.ts
// eventBus.ts
import mitt from 'mitt'
const mitter = mitt();
export default mitter
1.2.3. Use
- EventBus.vue
// EventBus.vue
<template>
<div>
Event Bus实现兄弟组件传参
<EventBusA />
<EventBusB />
</div>
</template>
<script setup lang="ts">
import EventBusA from './components/EventBusA.vue';
import EventBusB from './components/EventBusB.vue';
</script>
<style scoped>
</style>
- EventBusA.vue
// EventBusA.vue
<template>
<div class="wrapper">
兄弟组件A
<button type="button" @click="handleClick">点击传参</button>
</div>
</template>
<script setup lang="ts">
import {
ref } from 'vue';
import mitter from '@/utils/eventBus'
const msg = ref('Hello, world!')
const handleClick = () => {
mitter.emit('msg', msg.value)
}
</script>
<style scoped>
</style>
- EventBusB.vue
// EventBusB.vue
<template>
<div class="wrapper">
兄弟组件B
{
{ res }}
</div>
</template>
<script setup lang="ts">
import mitter from '@/utils/eventBus'
import {
ref } from 'vue'
const res = ref()
mitter.on('msg', (data) => {
res.value = data
})
</script>
<style scoped>
</style>
1.3. Communication between cross-level components
Provide/inject to realize communication between cross-level components
1.3.1 provide/inject
- parent.view
// parent.vue
<template>
<div class="wrapper">
兄弟组件传参,这是父组件
<brotherA />
<brotherB />
</div>
</template>
<script setup lang="ts">
import brotherA from './components/brotherA.vue'
import brotherB from './components/brotherB.vue'
import {
provide, ref } from 'vue';
let msg = ref('给孙组件传递的值');
provide('msg', msg)
</script>
<style scoped>
</style>
- brotherA.vue
// brotherA.vue
<template>
<div class="wrapper">
子组件A
<grandson />
</div>
</template>
<script setup lang="ts">
import grandson from "./grandson.vue";
import {
ref } from 'vue';
</script>
<style scoped>
</style>
- brotherB.vue
// brotherB.vue
<template>
<div class="wrapper">
子组件B
{
{ msg }}
</div>
</template>
<script setup lang="ts">
import {
inject } from 'vue'
let msg = inject('msg')
</script>
<style scoped>
</style>
- grandson.vue
// grandson.vue
<template>
<div class="wrapper">
这是孙组件
{
{ msg }}
</div>
</template>
<script setup lang="ts">
import {
inject } from 'vue'
let msg = inject('msg')
</script>
<style scoped>
</style>
1.4. Communication between non-parent-child components
1.4.1. Vuex/Pinia
Vuex and Pinia are the state management tools in Vue 3, using these two tools can easily achieve component communication. Since these two tools are relatively powerful, I will write an article to explain them in detail later.
Summarize
Component communication is a very important concept in Vue, which refers to the process of passing data and events between components. In Vue, component communication is mainly divided into communication between parent and child components and communication between sibling components.
In the communication between parent and child components, the parent component canv-bind
pass data to the child component through , and the child component candefineProps
receive the data passed by the parent component through . At the same time, child components can alsoemit
pass data to parent components by triggering custom events.
In the communication between sibling components, data transfer and event triggering can be realized through a common parent component, and data sharing can also be realized through state management tools such as Vuex.
In short, in the process of component communication, it is necessary to choose an appropriate method to realize the transfer of data and events, so as to achieve good cooperation and efficient interaction between components.