Vue3. Seven component communication modes of X

1, Premise

This kind of combination is more specific to the API composition method, which is equivalent to the free writing method vue document Description of two ways.

This article will introduce the following seven component communication modes:
● props
● emit
● v-model
● refs
● provide / inject
● eventBus
● vuex / pinia (status management tool)

2, Take an example


In the above figure, the list and input box are father son components. Depending on the way of simultaneous interpreting, the parent component and the sub components will be adjusted.

3, Use details

1. Props mode

Props is the most common method of parent-child transmission in Vue

The parent component code is as follows:

<template>
	<!--Subassembly label-->
	<child-components
  	:list="list"                  
  ></child-components>
	<!-- Parent component code -->
  <div class="child-wrap input-group">
    <input
      v-model="value"
      type="text"
      placeholder="Please enter"
    />  
  </div>
  <div class="input-group-append">
    <button
        @click="handleAdd"
        type="button"
     >add to</button>
  </div>	                
</template>
<script setup>
	import { ref } from 'vue'
  import ChildComponents from './child.vue'
  const list = ref(['JavaScript', 'HTML', 'CSS'])
  const value = ref('')
  // add event handling function after departure
  const handleAdd = () => {
  	list.value.push(value.value)
    value.value = ''
  }
</script>

Sub component code: you only need to render the value passed by the parent component. The code is as follows

<template>
	<ul>
    <li
    	v-for="i in props.list"
      :key="i"
    >{{ i }}</li>
  </ul>
</template>
<script setup>
	import { defineProps } from 'vue'
  const props = defineProps({
  	list: {
    	type: Array,
      default: () => []
    }
  })
</script>

2. emit mode

The emit mode is also the most common component communication mode in Vue, which is used to pass the child to the parent

The sub component codes are as follows:

<template>
	<div>
  	<input
       v-model="value"
       type="text" 
       placeholder="Please enter"
     />
    <div>
      <button
      	@click="handleSubmit"
        type="button"
      >add to</button>
  	</div>
  </div>
</template>
<script setup>
	import { ref, defineEmits } from 'vue'
  const value = ref('')
  const emits = defineEmits(['add'])
  const handleSubmit = () => {
  	emits('add', value.value)
    value.value = ''
  }
</script>

After clicking the [add] button in the sub component, emit a user-defined event and pass the added value as a parameter.

The parent component code is as follows:

<template>
	<ul>
    <li
    	v-for="i in list"
      :key="i"
    >{{ i }}</li>
  </ul>
	<!-- Subcomponents -->
	<child-component
  	@add="handleAdd"                 
  ></child-component>
</template>
<script setup>
	import { ref } from 'vue'
  import ChildComponents from './child.vue'
  const list = ref(['JavaScript', 'HTML', 'CSS'])
  // Event handling function triggered by add
  const handleAdd = value => {
  	list.value.push(value)
  }
</script>

3. v-model mode

v-model is an excellent syntax sugar in vue, such as the following code

<ChildComponent v-model:title="pageTitle" />

This is the short form of the following code

<ChildComponent
   :title="pageTitle"
   	@update:title="pageTitle = $event"                
/>

The sub component codes are as follows:

<template>
	<div>
  	<input
    	v-model="value"
      type="text"
      placeholder="Please enter"
    />
    <div>
      <button
      	@click="handleAdd"
        type="button"
      >add to</button>
  	</div>
  </div>
</template>
<script setup>
	import { ref, defineProps, defineEmits } from 'vue'
  const value = ref('')
  const props = defineProps({
  	list: {
    	type: Array,
      default: () => []
    }
  })
  const emits = defineEmits(['update:list'])
  // Add operation
  const handleAdd = () => {
  	const arr = props.list
    arr.push(value.value)
    emits('update:list', arr)
    value.value = ''
  }
</script>

In the subcomponent, we first define props and emit s, and then specify the event after adding.

Note: update: * is a fixed expression in vue* Represents a property name in props

The parent component code is as follows:

<template>
	<ul>
    <li
    	v-for="i in list"
      :key="i"
    >{{ i }}</li>
  </ul>
	<!--Subcomponents-->
	<child-components
  	v-model:list="list"                  
  ></child-components>
</template>
<script setup>
  	import { ref } from 'vue'
  	import ChildComponents from './child.vue'
  	const list = ref(['JavaScript', 'HTML', 'cSS'])
</script> 

4. ref mode

When using the optional API, we can use this$ refs. Name is used to obtain the specified element or component, but this method cannot be used in the composite API. If we want to obtain components or elements through Ref, we need to define a Ref object with the same name, which can be accessed after the component is mounted.

The parent component code is as follows:

<template>
	<ul>
    <li
    	v-for="i in childRefs?.list"
      :key="i"
    >{{ i }}</li>
  </ul>
	<!--Subcomponents ref Value and<script>Consistent in -->
	<child-components ref="childRefs"></child-components>
</template>
<script setup>
	import { ref } from 'vue'
  import ChildComponents from './child.vue'
  const childRefs = ref(null)
</script>

The sub component codes are as follows:

<template>
	<div>
  	<input v-model="value" type="text" placeholder="Please enter" />
    <div>
      <button
      	type="button"
        @click="handleAdd"
      >add to</button>
  	</div>
  </div>
</template>
<script setup>
  // Note the defineExpose here 
	import { ref, defineExpose } from 'vue'
  const list = ref(['JavaScript', 'HTML', 'CSS'])
  const value = ref('')
  // Event handling function triggered by add
  const handleAdd = () => {
  	list.value.push(value.value)
    value.value = ''
  }
  defineExpose({ list })
</script>

The setup component is closed by default, that is, the public instance of the component obtained through the template ref or $parent chain will not expose any binding declared in.
In order to specify the attributes to be exposed in the < script setup > component, use the defineExpose compiler macro.
You can view the details vue document

5. provide/inject mode

provide and inject are a pair of APIs provided in vue, which can transfer data from parent components to child components. No matter how deep the level is, they can be implemented through this pair of APIs.

The parent component code is as follows:

<template>
	<!--Subcomponents-->
	<child-components></child-components>
	<!--Parent component code-->
	<div>
  	<input v-model="value" type="text" placeholder="Please enter" />
    <div>
      <button
      	type="button"
        @click="handleAdd"
      >add to</button>
  	</div>
  </div>
</template>
<script setup>
	import { ref, provide } from 'vue'
  import ChildComponents from './child.vue'
  const list = ref(['JavaScript', 'HTML', 'CSS'])
  const value = ref('')
  // Provide data to subcomponents
  provide('list', list.value)
  // Event handling function triggered by add
  const handleAddd = () => {
  	list.value.push(value.value)
    value.value = ''
  }
</script>

The sub component codes are as follows:

<template>
	<ul>
    <li
    	v-for="i in list"
      :key="i"
    >{{ i }}</li>
  </ul>
</template>
<script setup>
	import { inject } from 'vue'
  // Receive data provided by parent component
  const list = inject('list')
</script>

It is worth noting that when using provide for data transmission, try to wrap the data readonly to avoid the child component modifying the data passed by the parent.

6. Event bus

Event bus is removed from vue3, but it can be completed with the help of third-party tools, which is officially recommended by Vue mitt or tiny-emitter
In most cases, it is not recommended to use the global event bus to realize component communication. Although it is relatively simple and rough, maintaining the event bus is a big problem for a long time. See Vue 3 for details X event bus

7. Status manager tool

vuex and pinia are vue3 The state management tools in X can easily realize component communication by using these two tools. Because these two tools are powerful, they will not be shown here. For details, please refer to the documents

summary

Reference documents: vue3. Seven communication modes of X

Keywords: Javascript Front-end Vue Vue.js

Added by NSW42 on Thu, 24 Feb 2022 07:58:49 +0200