search
HomeWeb Front-endVue.jsHow to communicate between components? Inventory of Vue component communication methods (worth collecting)

VueHow to communicate between components? This article takes stock of the 10 component communication methods of Vue2 and Vue3. I hope it will be helpful to everyone!

How to communicate between components? Inventory of Vue component communication methods (worth collecting)

There are many ways to communicate components in Vue, and there will be many differences in the implementation of Vue2 and Vue3; this article will use Optional API The three different implementation methods of combined API and setup comprehensively introduce the component communication methods of Vue2 and Vue3. The communication methods to be implemented are shown in the table below. (Learning video sharing: vue video tutorial)

method Vue2 Vue3
Pass from father to son props props
Pass from son to father $emit emits
From father to son $attrs attrs
son to father $listeners None (merged into attrs mode)
father to son provide provide
Child to parent inject inject
Child component accesses parent Component $parent None
Parent component accesses child component $children None
Parent component accesses child component $ref expose&ref
Brother passing value EventBus mitt

props

Props are one of the most commonly used communication methods in component communication. The parent component is passed in through v-bind, and the child component is received through props. The following are its three implementation methods

  • Optional API
//父组件

<template>
  <div>
    <child></child>
  </div>
</template>
<script>
import Child from &#39;./Child&#39;
export default {
  components:{
    Child
  },
  data() {
    return {
      parentMsg: &#39;父组件信息&#39;
    }
  }
}
</script>


//子组件

<template>
  <div>
    {{msg}}
  </div>
</template>
<script>
export default {
  props:[&#39;msg&#39;]
}
</script>
  • Combined Api
//父组件

<template>
  <div>
    <child></child>
  </div>
</template>
<script>
import { ref,defineComponent } from &#39;vue&#39;
import Child from &#39;./Child.vue&#39;
export default defineComponent({
  components:{
    Child
  },
  setup() {
    const parentMsg = ref(&#39;父组件信息&#39;)
    return {
      parentMsg
    };
  },
});
</script>

//子组件

<template>
    <div>
        {{ parentMsg }}
    </div>
</template>
<script>
import { defineComponent,toRef } from "vue";
export default defineComponent({
    props: ["msg"],// 如果这行不写,下面就接收不到
    setup(props) {
        console.log(props.msg) //父组件信息
        let parentMsg = toRef(props, &#39;msg&#39;)
        return {
            parentMsg
        };
    },
});
</script>
  • setup syntax sugar
//父组件

<template>
  <div>
    <child></child>
  </div>
</template>
<script>
import { ref } from &#39;vue&#39;
import Child from &#39;./Child.vue&#39;
const parentMsg = ref(&#39;父组件信息&#39;)
</script>

//子组件

<template>
    <div>
        {{ parentMsg }}
    </div>
</template>
<script>
import { toRef, defineProps } from "vue";
const props = defineProps(["msg"]);
console.log(props.msg) //父组件信息
let parentMsg = toRef(props, &#39;msg&#39;)
</script>

Note

The data flow in props is single item, that is, sub- Components cannot change the value passed by the parent component

In the combined API, if you want to use other variables to receive the value of props in the child component, you need to use toRef to convert the properties in the props to responsive.

emit

The child component can publish an event through emit and pass some parameters, and the parent component monitors this event through v-on

  • Option API
//父组件

<template>
  <div>
    <child></child>
  </div>
</template>
<script>
import Child from &#39;./Child&#39;
export default {
  components:{
    Child
  },
  methods: {
    getFromChild(val) {
      console.log(val) //我是子组件数据
    }
  }
}
</script>

// 子组件

<template>
  <div>
    <button>send</button>
  </div>
</template>
<script>
export default {
  methods:{
    sendFun(){
      this.$emit(&#39;sendMsg&#39;,&#39;我是子组件数据&#39;)
    }
  }
}
</script>
  • Combined API
//父组件

<template>
  <div>
    <child></child>
  </div>
</template>
<script>
import Child from &#39;./Child&#39;
import { defineComponent } from "vue";
export default defineComponent({
  components: {
    Child
  },
  setup() {
    const getFromChild = (val) => {
      console.log(val) //我是子组件数据
    }
    return {
      getFromChild
    };
  },
});
</script>

//子组件

<template>
    <div>
        <button>send</button>
    </div>
</template>

<script>
import { defineComponent } from "vue";
export default defineComponent({
    emits: [&#39;sendMsg&#39;],
    setup(props, ctx) {
        const sendFun = () => {
            ctx.emit(&#39;sendMsg&#39;, &#39;我是子组件数据&#39;)
        }
        return {
            sendFun
        };
    },
});
</script>
  • setup syntax sugar
//父组件

<template>
  <div>
    <child></child>
  </div>
</template>
<script>
import Child from &#39;./Child&#39;
const getFromChild = (val) => {
      console.log(val) //我是子组件数据
    }
</script>

//子组件

<template>
    <div>
        <button>send</button>
    </div>
</template>
<script>
import { defineEmits } from "vue";
const emits = defineEmits([&#39;sendMsg&#39;])
const sendFun = () => {
    emits(&#39;sendMsg&#39;, &#39;我是子组件数据&#39;)
}
</script>

attrs and listeners

The child component uses $attrs to obtain all attributes of the parent component except the attributes passed by props and the attribute binding attributes (class and style).

The sub-component uses $listeners to obtain all v-on event listeners of the parent component (excluding .native modifiers), which are no longer used in Vue3; but the attrs in Vue3 can not only obtain the parent component The passed properties can also be obtained from the parent component v-on event listener

  • Optional API
//父组件

<template>
  <div>
    <child></child>
  </div>
</template>
<script>
import Child from &#39;./Child&#39;
export default {
  components:{
    Child
  },
  data(){
    return {
      msg1:&#39;子组件msg1&#39;,
      msg2:&#39;子组件msg2&#39;
    }
  },
  methods: {
    parentFun(val) {
      console.log(`父组件方法被调用,获得子组件传值:${val}`)
    }
  }
}
</script>

//子组件

<template>
  <div>
    <button>调用父组件方法</button>
  </div>
</template>
<script>
export default {
  methods:{
    getParentFun(){
      this.$listeners.parentFun(&#39;我是子组件数据&#39;)
    }
  },
  created(){
    //获取父组件中所有绑定属性
    console.log(this.$attrs)  //{"msg1": "子组件msg1","msg2": "子组件msg2"}
    //获取父组件中所有绑定方法    
    console.log(this.$listeners) //{parentFun:f}
  }
}
</script>
  • Combined API
//父组件

<template>
  <div>
    <child></child>
  </div>
</template>
<script>
import Child from &#39;./Child&#39;
import { defineComponent,ref } from "vue";
export default defineComponent({
  components: {
    Child
  },
  setup() {
    const msg1 = ref(&#39;子组件msg1&#39;)
    const msg2 = ref(&#39;子组件msg2&#39;)
    const parentFun = (val) => {
      console.log(`父组件方法被调用,获得子组件传值:${val}`)
    }
    return {
      parentFun,
      msg1,
      msg2
    };
  },
});
</script>

//子组件

<template>
    <div>
        <button>调用父组件方法</button>
    </div>
</template>
<script>
import { defineComponent } from "vue";
export default defineComponent({
    emits: [&#39;sendMsg&#39;],
    setup(props, ctx) {
        //获取父组件方法和事件
        console.log(ctx.attrs) //Proxy {"msg1": "子组件msg1","msg2": "子组件msg2"}
        const getParentFun = () => {
            //调用父组件方法
            ctx.attrs.onParentFun(&#39;我是子组件数据&#39;)
        }
        return {
            getParentFun
        };
    },
});
</script>
  • setup syntax sugar
//父组件

<template>
  <div>
    <child></child>
  </div>
</template>
<script>
import Child from &#39;./Child&#39;
import { ref } from "vue";
const msg1 = ref(&#39;子组件msg1&#39;)
const msg2 = ref(&#39;子组件msg2&#39;)
const parentFun = (val) => {
  console.log(`父组件方法被调用,获得子组件传值:${val}`)
}
</script>

//子组件

<template>
    <div>
        <button>调用父组件方法</button>
    </div>
</template>
<script>
import { useAttrs } from "vue";

const attrs = useAttrs()
//获取父组件方法和事件
console.log(attrs) //Proxy {"msg1": "子组件msg1","msg2": "子组件msg2"}
const getParentFun = () => {
    //调用父组件方法
    attrs.onParentFun(&#39;我是子组件数据&#39;)
}
</script>

Note

When using attrs to call the parent component method in Vue3, on needs to be added before the method; for example parentFun->onParentFun

provide/inject

provide: is an object, or a function that returns an object. It contains the attributes to be given to future generations

inject: a string array, or an object. Get the value provided by the parent component or higher-level component, which can be obtained in any descendant component through inject

  • Optional API
//父组件
<script>
import Child from &#39;./Child&#39;
export default {
  components: {
    Child
  },
  data() {
    return {
      msg1: &#39;子组件msg1&#39;,
      msg2: &#39;子组件msg2&#39;
    }
  },
  provide() {
    return {
      msg1: this.msg1,
      msg2: this.msg2
    }
  }
}
</script>

//子组件

<script>
export default {
  inject:[&#39;msg1&#39;,&#39;msg2&#39;],
  created(){
    //获取高层级提供的属性
    console.log(this.msg1) //子组件msg1
    console.log(this.msg2) //子组件msg2
  }
}
</script>
  • Combined type API
//父组件

<script>
import Child from &#39;./Child&#39;
import { ref, defineComponent,provide } from "vue";
export default defineComponent({
  components:{
    Child
  },
  setup() {
    const msg1 = ref(&#39;子组件msg1&#39;)
    const msg2 = ref(&#39;子组件msg2&#39;)
    provide("msg1", msg1)
    provide("msg2", msg2)
    return {
      
    }
  },
});
</script>

//子组件

<template>
    <div>
        <button>调用父组件方法</button>
    </div>
</template>
<script>
import { inject, defineComponent } from "vue";
export default defineComponent({
    setup() {
        console.log(inject(&#39;msg1&#39;).value) //子组件msg1
        console.log(inject(&#39;msg2&#39;).value) //子组件msg2
    },
});
</script>
  • setup syntax sugar
//父组件
<script>
import Child from &#39;./Child&#39;
import { ref,provide } from "vue";
const msg1 = ref(&#39;子组件msg1&#39;)
const msg2 = ref(&#39;子组件msg2&#39;)
provide("msg1",msg1)
provide("msg2",msg2)
</script>

//子组件

<script>
import { inject } from "vue";
console.log(inject(&#39;msg1&#39;).value) //子组件msg1
console.log(inject(&#39;msg2&#39;).value) //子组件msg2
</script>

Description

provide/inject is generally in deep component nesting Use appropriately. Generally used in component development.

parent/children

$parent: The child component obtains the Vue instance of the parent component, and can obtain the properties and methods of the parent component, etc.

$children: Parent The component obtains the Vue instance of the sub-component, which is an array and a collection of direct children, but the order of the sub-components is not guaranteed

  • Vue2
import Child from './Child'
export default {
  components: {
    Child
  },
  created(){
    console.log(this.$children) //[Child实例]
    console.log(this.$parent)//父组件实例
  }
}

NoteThe $children obtained by the parent component is not responsive

expose&ref

$refs can directly obtain element attributes, and can also Directly obtain the sub-component instance

  • Optional API
//父组件

<template>
  <div>
    <child></child>
  </div>
</template>
<script>
import Child from &#39;./Child&#39;
export default {
  components: {
    Child
  },
  mounted(){
    //获取子组件属性
    console.log(this.$refs.child.msg) //子组件元素

    //调用子组件方法
    this.$refs.child.childFun(&#39;父组件信息&#39;)
  }
}
</script>

//子组件 

<template>
  <div>
    <div></div>
  </div>
</template>
<script>
export default {
  data(){
    return {
      msg:&#39;子组件元素&#39;
    }
  },
  methods:{
    childFun(val){
      console.log(`子组件方法被调用,值${val}`)
    }
  }
}
</script>
  • Combined API
//父组件

<template>
  <div>
    <child></child>
  </div>
</template>
<script>
import Child from &#39;./Child&#39;
import { ref, defineComponent, onMounted } from "vue";
export default defineComponent({
  components: {
    Child
  },

  setup() {
    const child = ref() //注意命名需要和template中ref对应
    onMounted(() => {
      //获取子组件属性
      console.log(child.value.msg) //子组件元素

      //调用子组件方法
      child.value.childFun(&#39;父组件信息&#39;)
    })
    return {
      child //必须return出去 否则获取不到实例
    }
  },
});
</script>

//子组件

<template>
    <div>
    </div>
</template>
<script>
import { defineComponent, ref } from "vue";
export default defineComponent({
    setup() {
        const msg = ref(&#39;子组件元素&#39;)
        const childFun = (val) => {
            console.log(`子组件方法被调用,值${val}`)
        }
        return {
            msg,
            childFun
        }
    },
});
</script>
  • setup syntax sugar
//父组件

<template>
  <div>
    <child></child>
  </div>
</template>
<script>
import Child from &#39;./Child&#39;
import { ref, onMounted } from "vue";
const child = ref() //注意命名需要和template中ref对应
onMounted(() => {
  //获取子组件属性
  console.log(child.value.msg) //子组件元素

  //调用子组件方法
  child.value.childFun(&#39;父组件信息&#39;)
})
</script>

//子组件

<template>
    <div>
    </div>
</template>
<script>
import { ref,defineExpose } from "vue";
const msg = ref(&#39;子组件元素&#39;)
const childFun = (val) => {
    console.log(`子组件方法被调用,值${val}`)
}
//必须暴露出去父组件才会获取到
defineExpose({
    childFun,
    msg
})
</script>

Note

Obtaining the subcomponent instance through ref must be obtained after the page is mounted.

When using setup syntax sugar, the child component must expose elements or methods to the parent component in order to obtain

EventBus/mitt

sibling component communication It can be implemented through an event center EventBus, which creates a new Vue instance to monitor, trigger and destroy events.

There is no EventBus sibling component communication in Vue3, but now there is an alternative solutionmitt.js, the principle is still EventBus

  • Optional API
//组件1
<template>
  <div>
    <button>传值</button>
  </div>
</template>
<script>
import Bus from &#39;./bus.js&#39;
export default {
  data(){
    return {
      msg:&#39;子组件元素&#39;
    }
  },
  methods:{
    sendMsg(){
      Bus.$emit(&#39;sendMsg&#39;,&#39;兄弟的值&#39;)
    }
  }
}
</script>

//组件2

<template>
  <div>
    组件2
  </div>
</template>
<script>
import Bus from &#39;./bus.js&#39;
export default {
  created(){
   Bus.$on(&#39;sendMsg&#39;,(val)=>{
    console.log(val);//兄弟的值
   })
  }
}
</script>

//bus.js

import Vue from "vue"
export default new Vue()
  • Combined API

First install mitt

npm i mitt -S

and then create a new one like bus.js in Vue2mitt.jsFile

mitt.js

import mitt from 'mitt'
const Mitt = mitt()
export default Mitt
//组件1
<template>
     <button>传值</button>
</template>
<script>
import { defineComponent } from "vue";
import Mitt from &#39;./mitt.js&#39;
export default defineComponent({
    setup() {
        const sendMsg = () => {
            Mitt.emit(&#39;sendMsg&#39;,&#39;兄弟的值&#39;)
        }
        return {
           sendMsg
        }
    },
});
</script>

//组件2
<template>
  <div>
    组件2
  </div>
</template>
<script>
import { defineComponent, onUnmounted } from "vue";
import Mitt from &#39;./mitt.js&#39;
export default defineComponent({
  setup() {
    const getMsg = (val) => {
      console.log(val);//兄弟的值
    }
    Mitt.on(&#39;sendMsg&#39;, getMsg)
    onUnmounted(() => {
      //组件销毁 移除监听
      Mitt.off(&#39;sendMsg&#39;, getMsg)
    })

  },
});
</script>
  • setup syntax sugar
//组件1

<template>
    <button>传值</button>
</template>
<script>
import Mitt from &#39;./mitt.js&#39;
const sendMsg = () => {
    Mitt.emit(&#39;sendMsg&#39;, &#39;兄弟的值&#39;)
}
</script>

//组件2

<template>
  <div>
    组件2
  </div>
</template>
<script>
import { onUnmounted } from "vue";
import Mitt from &#39;./mitt.js&#39;
const getMsg = (val) => {
  console.log(val);//兄弟的值
}
Mitt.on(&#39;sendMsg&#39;, getMsg)
onUnmounted(() => {
  //组件销毁 移除监听
  Mitt.off(&#39;sendMsg&#39;, getMsg)
})
</script>

Write at the end

In fact, components can also communicate with Vuex or Pinia state management tools (but this is generally not recommended for communication between components, because this will cause the problem that components cannot be reused). For the usage of Vuex and Pinia, you can refer to this article An article analyzing Pinia and Vuex

(Learning video sharing: web front-end development, Basic programming video )

The above is the detailed content of How to communicate between components? Inventory of Vue component communication methods (worth collecting). For more information, please follow other related articles on the PHP Chinese website!

Statement
This article is reproduced at:掘金社区. If there is any infringement, please contact admin@php.cn delete
Netflix's Frontend: Examples and Applications of React (or Vue)Netflix's Frontend: Examples and Applications of React (or Vue)Apr 16, 2025 am 12:08 AM

Netflix uses React as its front-end framework. 1) React's componentized development model and strong ecosystem are the main reasons why Netflix chose it. 2) Through componentization, Netflix splits complex interfaces into manageable chunks such as video players, recommendation lists and user comments. 3) React's virtual DOM and component life cycle optimizes rendering efficiency and user interaction management.

The Frontend Landscape: How Netflix Approached its ChoicesThe Frontend Landscape: How Netflix Approached its ChoicesApr 15, 2025 am 12:13 AM

Netflix's choice in front-end technology mainly focuses on three aspects: performance optimization, scalability and user experience. 1. Performance optimization: Netflix chose React as the main framework and developed tools such as SpeedCurve and Boomerang to monitor and optimize the user experience. 2. Scalability: They adopt a micro front-end architecture, splitting applications into independent modules, improving development efficiency and system scalability. 3. User experience: Netflix uses the Material-UI component library to continuously optimize the interface through A/B testing and user feedback to ensure consistency and aesthetics.

React vs. Vue: Which Framework Does Netflix Use?React vs. Vue: Which Framework Does Netflix Use?Apr 14, 2025 am 12:19 AM

Netflixusesacustomframeworkcalled"Gibbon"builtonReact,notReactorVuedirectly.1)TeamExperience:Choosebasedonfamiliarity.2)ProjectComplexity:Vueforsimplerprojects,Reactforcomplexones.3)CustomizationNeeds:Reactoffersmoreflexibility.4)Ecosystema

The Choice of Frameworks: What Drives Netflix's Decisions?The Choice of Frameworks: What Drives Netflix's Decisions?Apr 13, 2025 am 12:05 AM

Netflix mainly considers performance, scalability, development efficiency, ecosystem, technical debt and maintenance costs in framework selection. 1. Performance and scalability: Java and SpringBoot are selected to efficiently process massive data and high concurrent requests. 2. Development efficiency and ecosystem: Use React to improve front-end development efficiency and utilize its rich ecosystem. 3. Technical debt and maintenance costs: Choose Node.js to build microservices to reduce maintenance costs and technical debt.

React, Vue, and the Future of Netflix's FrontendReact, Vue, and the Future of Netflix's FrontendApr 12, 2025 am 12:12 AM

Netflix mainly uses React as the front-end framework, supplemented by Vue for specific functions. 1) React's componentization and virtual DOM improve the performance and development efficiency of Netflix applications. 2) Vue is used in Netflix's internal tools and small projects, and its flexibility and ease of use are key.

Vue.js in the Frontend: Real-World Applications and ExamplesVue.js in the Frontend: Real-World Applications and ExamplesApr 11, 2025 am 12:12 AM

Vue.js is a progressive JavaScript framework suitable for building complex user interfaces. 1) Its core concepts include responsive data, componentization and virtual DOM. 2) In practical applications, it can be demonstrated by building Todo applications and integrating VueRouter. 3) When debugging, it is recommended to use VueDevtools and console.log. 4) Performance optimization can be achieved through v-if/v-show, list rendering optimization, asynchronous loading of components, etc.

Vue.js and React: Understanding the Key DifferencesVue.js and React: Understanding the Key DifferencesApr 10, 2025 am 09:26 AM

Vue.js is suitable for small to medium-sized projects, while React is more suitable for large and complex applications. 1. Vue.js' responsive system automatically updates the DOM through dependency tracking, making it easy to manage data changes. 2.React adopts a one-way data flow, and data flows from the parent component to the child component, providing a clear data flow and an easy-to-debug structure.

Vue.js vs. React: Project-Specific ConsiderationsVue.js vs. React: Project-Specific ConsiderationsApr 09, 2025 am 12:01 AM

Vue.js is suitable for small and medium-sized projects and fast iterations, while React is suitable for large and complex applications. 1) Vue.js is easy to use and is suitable for situations where the team is insufficient or the project scale is small. 2) React has a richer ecosystem and is suitable for projects with high performance and complex functional needs.

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Chat Commands and How to Use Them
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Dreamweaver Mac version

Dreamweaver Mac version

Visual web development tools

PhpStorm Mac version

PhpStorm Mac version

The latest (2018.2.1) professional PHP integrated development tool

SublimeText3 English version

SublimeText3 English version

Recommended: Win version, supports code prompts!

DVWA

DVWA

Damn Vulnerable Web App (DVWA) is a PHP/MySQL web application that is very vulnerable. Its main goals are to be an aid for security professionals to test their skills and tools in a legal environment, to help web developers better understand the process of securing web applications, and to help teachers/students teach/learn in a classroom environment Web application security. The goal of DVWA is to practice some of the most common web vulnerabilities through a simple and straightforward interface, with varying degrees of difficulty. Please note that this software

mPDF

mPDF

mPDF is a PHP library that can generate PDF files from UTF-8 encoded HTML. The original author, Ian Back, wrote mPDF to output PDF files "on the fly" from his website and handle different languages. It is slower than original scripts like HTML2FPDF and produces larger files when using Unicode fonts, but supports CSS styles etc. and has a lot of enhancements. Supports almost all languages, including RTL (Arabic and Hebrew) and CJK (Chinese, Japanese and Korean). Supports nested block-level elements (such as P, DIV),