Due to the impact of the epidemic, I have been working from home for a while. Recently, I have had time to talk about my understanding and use of Vue3.2 + TS knowledge. Today I will summarize the communication between some commonly used components in the project.
The vue framework provides the idea of front-end development components. The page is composed of components one by one. In some large-scale projects, the number of components is increasing and communication is needed. Next, let’s go to the topic and talk about how to use component communication in +ts.
(The communication between the components in the middle is basically not very different from 2, but the writing method based on ts may be a bit different.)
Parent-child component communication
1、defineProps
Parent
<template> <child :count= "countNum" :labels="labels" /> </template> <script setup lang="ts"> import child from "@/componets/" import { ref } from "vue" const countNum = ref(100); const labels = ref([]) </script>
Child
<template> <div>{{count}}</div> </template> <script setup lang="ts"> // Here we use typescript to writetype TData = { count:number,labels:string[] } //Declare the data and type of parent component passed by//This writing method cannot set the default valueconst props = defineProps<TData>() //Writing the default valueconst props = withDefaults( defineProps<TData>(), { count:1, labels:() => ["Default value 1","Default value 2"] //Declare complex data types in functional form}) () // You can get the value directly in the template</script>
2、defineEmits
Parent
<template> <child @changeHandle="changeHandle" /> </template> <script setup lang="ts"> import child from "@/componets/" const changeHandle = ((e) =>{ (e) }) </script>
Child
<template> <div @click="btnHandle">Button click</div> </template> <script setup lang="ts"> import { ref } from "vue" const count = ref(100); //Typescript writingtype TFn = { (e:'changeHandle',value:number) : void } const emit = defineEmits<TFn>() const btnHandle = (() => { emit('changeHandle',count) }) //Non-typescript writingconst emit = defineEmits(["changeHandle"]) const btnHandle = (() => { emit('changeHandle',count) }) </script>
3、defineExpose
The documentation is described in this way:
Components using <script setup> are closed by default, that is, public instances of components obtained through template ref or $parent chain will not expose any bindings declared in <script setup>. In order to clarify the properties to be exposed in the <script setup> component, use the defineExpose compiler macro (in fact, it can be understood that the parent component wants to obtain the content of the child component, and the child component exposes the content through defineExpose)
Parent
<template> <child ref="getChild" /> <div @click="btnHandle">Button click</div> </template> <script setup lang="ts"> import child from "@/componets/" const getChild = ref(null) const btnHandle = () => { //Get the content exposed by the child component through ref () (()) } </script>
Child
<template> <div @click="btnHandle">Button click</div> </template> <script setup lang="ts"> import { ref } from "vue" const count = ref(100); const btnHandle = () => { count++ } defineExpose({count,btnHandle}) </script>
4、v-model
When communication between parents and children, sometimes the child component needs to modify the content passed by the parent component, use the value passed by defineProps, and modifying it will cause an error. I listen through watch in it, and then assign the new value to custom properties in the data.
In this, we can pass the v-model and modify the value, let's operate it directly!
<template> <A v-model:count="count"></A> </template> <script setup lang="ts"> import A from "@/components/" import { ref } from "vue" const count = ref(100); </script> <template> <div>{{count}}</div> <div @click="updateHandle">Modify content</div> </template> <script setup lang="ts"> import { ref } from "vue" const props = defineProps<{count:number}>() //Reviseconst emit = defineEmits(["update:count"]) const updateHandle = () => { emit("update:count",10) } </script>
Brother Component Communication
In this article, we generally use the central event bus (eventBus) to handle sibling components, and in vue3, mitt() is used to handle communication between sibling components. The actual usage is the same as eventBus. Let's take a look at how to implement it.
mitt
Step 1 Installation:
yarn add mitt -S
Step 2 Create
//Create in src/utilsimport mitt from "mitt" const mitter = mitt() default export mitter
Step 3 Use
//Brother A component<template> <div @click="btnHandle">Button click</div> </template> <script setup lang="ts"> import mitter from "@/utils/" import { ref } from "vue" const count = ref(100) ("count",) </script> //Brother B component<template> <div @click="btnHandle">Button click</div> </template> <script setup lang="ts"> import mitter from "@/utils/" import { ref } from "vue" const getCount = ref() ("count",(e) => { = e }) </script>
Cross-component communication
Provide/Inject
There is often communication between components in the business. Some students may think of passing them layer by layer through defineProps, which can be achieved, but it is difficult to maintain the project with a huge amount of code.
//provide receives two parameters 1. name<String type> 2. value<template> <A></A> </template> <script setup lang="ts"> import mitter from "@/utils/" import A from "@/components/" import { provide } from "vue" const count = ref(190) provide('count',) </script> <!--AIn the componentBComponents--> //inject receives two parameters 1. Provide the name that comes if it is sent 2. Optional parameters, provide the default value<template> <div>I amBComponents</div> </template> <script setup lang="ts"> import mitter from "@/utils/" import { inject } from "vue" const getCount = inject('count',11) </script>
This is the end of this article about the implementation of communication between Vue3.2+Ts components. For more information about communication content related to Vue3.2 Ts components, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!