Summary of communication methods of vue3 components

Summary of communication methods of vue3 components

1. props (from father to son)

The parent component passes values ​​to the child component, and the child component obtains the data passed by the parent component through defineProps.
parent component

<template>
   <Child info="小心" :money="money"></Child>
</template>

<script setup lang="ts">
import Child from "./Child.vue";
import {
    
     ref } from "vue";
let money = ref(10000);
</script>

Subassembly

<template>
   <p>{
    
    {
    
     info }}</p>
   <p>{
    
    {
    
     money }}</p>
</template>
<script setup lang="ts">
//使用defineProps方法接受父组件传递过来的数据
const props = defineProps(["info", "money"]); //数组写法
// const props = defineProps({  //对象写法
//   info: String,
//   money: Number,
// });
</script>
  • Note: the way of writing in vue2
//props:['name'] 	//方式1
//props:{name:String}	//方式2
props:{
    
    	//方式3
	name:{
    
    
        type:String, //类型
      ​  required:true, //必要性default:'老王' //默认值
    }
}

2.emit (from son to father)

Passing from child to parent is realized through custom events, and custom events are triggered through emit in child components.
parent component

<template>
  <!-- 绑定自定义事件xxx:实现子组件给父组件传递数据 -->
  <Child @xxx="handler"></Child>
</template>
<script setup lang="ts">
import Child from "./Child.vue";
const handler = (param1: any, param2: any) => {
    
    
  console.log(param1, param2); //小,心
};
</script>

Subassembly

<template>
  <button @click="handler">子传父</button>
</template>
<script setup lang="ts">
//利用defineEmits方法返回函数触发自定义事件
let emit = defineEmits(["xxx"]);
const handler = () => {
    
    
  emit("xxx", "小", "心");
};
</script>
  • Note: The way of writing in vue2 is triggered directly through the vue instance object
this.$emit('xxx',数据);

3.mitt plugin (global event bus)

The global event bus can realize arbitrary component communication. The eventBus is removed in Vue 3, but it can be realized by using the mitt plug-in.
Usage reference mitt official website
installation

npm install --save mitt

Use
insert image description here
the emit method to distribute custom events, and the on method to bind custom event listeners.

  • Note: Written in vue2
 new Vue({
    
    
    ......
    beforeCreate() {
    
    
        Vue.prototype.$bus = this //安装全局事件总线
    },
    ......
}) 
this.$bus.$on('xxxx',this.demo)	//需要接受数据的组件中给$bus绑定自定义事件
this.$bus.$emit('xxxx',数据)	//另一个组件中提供数据

4.v-model (parent-child component data synchronization)

v-model can realize two-way binding of form data.
In addition, v-model can also realize parent-child component data synchronization, which is similar to the syntactic sugar of xxxx.sync in vue2.
Requirement: Click the button, and the parent-child component data will change synchronously.
insert image description here
insert image description here

  • Method 1: Use props and emit to realize parent-child component synchronization

Parent component: Pass the money data to the child component, and accept the money update data passed by the child component in the custom event update:modelValue.
insert image description here
Child component: Accept the money passed by the parent component through props, and trigger a custom event through emit to update the data of the parent component.
insert image description here

  • Method 2: Use v-model to simplify

insert image description here
The essence of v-model is realized by using props[modelValue] and custom event [update:modelValue]. It is equivalent to passing a props[modelValue] to the child component Child and binding a custom event update:modelValue, which
can be seen through the developer tool.
insert image description here
At the same time, multiple data synchronization between parent and child components can be realized by using multiple v-models.

<!-- 相当于给组件Child传递两个props分别是pageOne与pageTwo,以及绑定两个自定义事件update:pageOne与update:pageTwo实现父子数据同步 -->
<Child v-model:pageOne="msg1" v-model:pageTwo="msg2"></Child>

Supplement: pagination in elementPlus also uses v-model.insert image description here

  • Note: .async usage in vue2

:money.async represents the parent component to pass the string props[money] to the child component, and bind a custom event (update:money) to the current child component

<template>
    <Money :money.sync="money"/>
    <!--等价于 -->
    <Money :money="money" @update:money="money=$event">
</template>

5. useAttrs (father and child)

In Vue3, you can use the useAttrs method to get the attributes and events of the parent component (including native DOM events and custom events). Similar to props, it can accept properties and property values ​​​​passed by parent components.
Case: Use el-button to encapsulate a component so that it has a prompt function.
Parent component Child insert image description here
component Get the properties and events on the component
through methods. In addition, the writing method can be used on el-button , but this is too cumbersome. If the passed attribute name is consistent with the attribute name of the bound tag, use the form of: = "$attrs" directly.useAttrs
type=”$attrs.type“ size="$attrs.size"......

<template>
  <div :title="title">
    <el-button :="$attrs"></el-button>
  </div>
</template>
<script setup lang="ts">
//引入useAttrs方法:获取组件标签身上属性与事件
import {
    
     useAttrs } from "vue";
let $attrs = useAttrs();
let props = defineProps(["title"]);
console.log($attrs);
</script>

insert image description here
insert image description here

  • important point:

If defineProps accepts an attribute, the object returned by the useAttrs method does not have the corresponding attribute and attribute value. Here the title has been accepted with props, and the useAttrs method cannot get the title.
insert image description here
insert image description here

  • Note: Written in Vue2: use $attrsattributes and$listeners

$attrsIt is a property of the component instance, which can get the props data passed by the parent component; $listenersit is a property of the component instance, which can get the custom event passed by the parent component to the child component;
similarly, if the property received by the child component through props, in the $attrs property It is unobtainable among them.
parent component:

<template>
    <ElButton type="success" icon="el-icon-delete" size="mini" title="按钮" @click="handler"/>
</template>

Subassembly

<template>
  <a :title="title">
      <el-button v-bind="$attrs" v-on="$listeners"></el-button>
  </a>
</template>
<script>
export default {
    
    
    props:['title'],
    mounted(){
    
    
        console.log(this.$attrs);
    }
}
</script>

6.ref/$parent (parent-child component communication)

6.1 ref

ref is used to register references of elements or subcomponents, that is, DOM element and subcomponent instances can be obtained.
Then you can pass the child to the parent through ref, and use the data and methods of the child component in the parent component.

  • 1. When using the option API, the reference will be registered in the this.$refs object of the component:
<!-- 存储为 this.$refs.p -->
<p ref="p">hello</p>
  • 2. When using the composite API, the reference will be stored in the ref matching the name:

insert image description here
If used on a normal DOM element, the reference will be the element itself; if used on a subcomponent, the reference will be the subcomponent's instance.

  • important point:

Components using script setup in vue3 are closed by default and cannot be accessed externally. If you want the parent component to obtain the data or methods of the child component, you need to specify the properties that need to be exposed to the outside world through defineExpose in the child component.
Example:
parent component
insert image description here
child component
insert image description here

6.2 $parent

$parent can get the parent component instance of the current component, so the data and methods of the parent component can be obtained in the child component.
parent component. The data and methods of the parent component need to be exposed externally through the defineExpose method

<template>
    <Child></Child>
</template>

<script setup lang="ts">
import Child from "./Child.vue";
import {
    
     ref } from "vue";
let yourMoney = ref(666);
let myMoney = ref(10);
defineExpose({
    
    
  yourMoney,
  myMoney,
});
</script>

Subassembly. Get the parent component instance when the button inside the child component is clicked.

<template>
  <div class="dau">
    <button @click="handler($parent)">点击获取父组件实例</button>
  </div>
</template>
<script setup lang="ts">
const handler = ($parent) => {
    
    
  console.log($parent.yourMoney); //666
  console.log($parent.myMoney); //10
};
</script>
  • Note: Written in vue2

Vue2 can also be used $childrento get all instances of all subcomponents of the current component. It was removed
in vue3 and replaced by $refs.$children

7.provide/inject (communication between ancestor and descendant components)

Vue3 provides two methods provide and inject, no matter how deep the level is, the API can realize the data transfer from the parent component to the descendant component.

7.1 provide (provide)

provide is used to provide values ​​that can be injected by descendant components.
insert image description here
parent component

<script setup lang="ts">
import Child from "./Child.vue";
import {
    
     ref, provide } from "vue";
let car = ref("小星星");
//祖先组件给后代组件提供数据
//第一个参数就是提供的数据key
//第二个参数是提供的数据
provide("TOKEN", star);
</script>

7.2 inject (injection)

Descendant components can obtain data through the inject method, and obtain stored values ​​through the key.
Subassembly

<template>
  <div class="child1">
    <h1>孙子组件</h1>
    <p>{
    
    {
    
     star }}</p>
    <button @click="updateCar">更新数据</button>
  </div>
</template>

<script setup lang="ts">
import {
    
     inject } from "vue";
//注入祖先组件提供数据
//需要参数:即为祖先提供数据的key
let star = inject("TOKEN");
console.log(star.value);	//小星星
//后代组件可以修改注入的值,祖先组件提供的值也会跟着变
const updateCar = () => {
    
    
  star.value = "摘下月亮";	
};
</script>
</script>

Note: descendant components can modify the injected value, and the value provided by the ancestor component will also change.
Effect
insert image description here
insert image description here

8. slot (parent-child component communication)

Slots: divided into default slots, named slots, and scoped slots, which can realize parent-child component communication.

8.1 Default slots

Use the slot global component tag inside the child component

<template>
  <div>
    <slot></slot>
  </div>
</template>
<script setup lang="ts">
</script>
<style scoped>
</style>

parent component. Todo is a subcomponent, and the internal writing structure of the double label is passed to the subcomponent.

<Todo>
  <h1>我是默认插槽填充的结构</h1>
</Todo>

8.2 Named slots

Leave multiple named slots inside the component with a name Child
component with two named slots

<template>
  <div>
    <h1>todo</h1>
    <slot name="a"></slot>
    <slot name="b"></slot>
  </div>
</template>
<script setup lang="ts">
</script>

<style scoped>
</style>

Parent Component
The parent component internally passes the struct to the specified named slot. Use v-slot: , which can be replaced with #.

<template>
  <div>
    <h1>slot</h1>
    <Todo>
      <template v-slot:a>  //可以用#a替换
        <div>填入组件A部分的结构</div>
      </template>
      <template #b>//可以用#b替换
        <div>填入组件B部分的结构</div>
      </template>
    </Todo>
  </div>
</template>

<script setup lang="ts">
import Todo from "./Todo.vue";
</script>
<style scoped>
</style>

8.3 Scoped slots

Scope slot: It is a slot that can transfer data . The child component can pass the data to the parent component , and the parent component can decide what structure or appearance the returned data should be displayed inside the child component.
In the following example, the parent component passes the todos data to the child component, the child component accepts the value of the parent component, and sends the data back to the parent component through the scope slot, and the parent component sets the style for the data.
parent component child
insert image description here
component
insert image description here

Effect
insert image description here

  • Note: The parent component in vue2 obtains the data of the child component through the scope attribute value
<template scope="scopeData">
     <ul>
         <li v-for="g in scopeData.games" :key="g">{
   
   {g}}</li>
     </ul>
 </template>

9. pinia/vuex (arbitrary component communication)

Vue3 can use Pinia and Vuex4 , two centralized management state containers, to achieve arbitrary component communication .

  • Vuex core concepts: state, mutations, actions, getters, modules
  • Pinia core concepts: state, actions, getters. There are no mutations and modules.

Usage reference: Pinia official website , Vuex official website

  • Note: Vuex3 is used in vue2, and Pinia can also be used.

Guess you like

Origin blog.csdn.net/weixin_43288600/article/details/130765494