A very detailed summary of communication between Vue components

A very detailed summary of communication between Vue components

Preface

Component communication plays a vital role in our daily development process, especially in Vue and React. This article will summarize several ways of communication between components in Vue:

  • props, $emit
  • $parent、$children
  • $attrs, $listeners
  • provide、inject
  • eventBus
  • vuex
  • Local Storage

1. Props, $emit one-way data flow

father.vue:

<template>
  <div>
    <div>I am a father: <input type="button" value="father" /> The number is: {{num}}</div>
    <son :num="num" @change="change"></son>
  </div>
</template>

<script>
import son from "./son.vue";
export default {
  name: "Father",
  components:
    son,
  },
  data() {
    return {
      num: 1,
    };
  },
  methods:{
    change(val){
      this.num = val
    }
  }
};
</script>

son.vue:

<template>
  <div>I am a son: <input type="button" value="son" @click="change"/>The number is: {{num}}</div>
</template>

<script>
export default {
  name: "App",
  components: {},
  props: {
    num: {
      default: 0,
    },
  },
  created() {},
  methods: {
    change(){
      // this.num = 2 props communication is a one-way data flow. Directly modifying the num passed by the parent component here will result in an error. // You can use $emit to trigger the change event. The father component binds the change event this.$emit('change', 2)
    }
  },
};
</script> 

For the above scenario: the change event of the child component is just to modify a value in the parent component. There are also several ways to write it:

1. Parent components bind events to child components using arrow functions

father:
<son :num="num" @change="val => num = val"></son>

son:
this.$emit('change', 2)

2.update:num and .sync

father:

<son :num.sync="num"></son>

son:

this.$emit('update:num', 2) //update is a prescribed way of writing and cannot be changed

3.v-model

First modify the props and bound events:

father: <son :value="num" @input="val => num = val"></son> son: this.$emit('input', 2) 
Available v-model abbreviation: <son v-model="num"></son>

2. $parent, $children

$parent and $children can directly call their respective methods and modify data in parent and child components

Directly in the child component: this.$parent.num = 2

In the parent component, $children is an array, so it is not very intuitive which child component it is. You can use $refs to operate the child component.

Vue officially does not recommend this method of communication: use $parent and $children sparingly - their main purpose is to serve as an emergency method for accessing components. It is recommended to use props and events to achieve parent-child component communication.

3. $attrs, $listeners

$attrs can get the attributes passed from the parent component:

<div>I am a son: <input type="button" value="son" @click="change"/>The number is: {{$attrs}}</div> 

dom node:

$attrs will directly put the passed attributes on the corresponding tags, while props will not. If you want to remove these attributes from the tag, you can use inheritAttrs:

It is worth noting that props has a higher priority than $attrs, that is, when props exists, $attrs is an empty object:

$attrs is often used to pass attributes across multiple levels of components, such as grandparent components, using the parent component as a transit:

father:

<son v-bind="$attrs"></son>

$attrs is used for cross-level attribute transfer, while $listeners is used for cross-level method transfer.

grandFather.vue:

<template>
  <div>
    <div>I am a grandfather: The number is: {{nums}}</div>
    <father :nums="nums" @up="up" @down="down"></father>
  </div>
</template>

<script>
import father from "./father.vue";
export default {
  name: "App",
  components:
    father,
  },
  data(){
    return {
      nums:0
    }
  },
  methods: {
    up() {
      alert('up')
    }, down() { alert('down') },
  },
};
</script>

father.vue:

<son v-bind="$attrs" v-on="$listeners"></son>

son.vue:

<div>I am a son: <input type="button" value="son" @click="$listeners.up"/></div> 

4. provide, inject

This pair of options should be used together to allow an ancestor component to inject a dependency into all its descendants, no matter how deep the component hierarchy is, and always take effect as long as the upstream and downstream relationships are established.

The provide option should be an object or a function that returns an object.

The inject option should be an array of strings or an object.

App:

...

export default {
  provide(){
    return {vm: this}
  },

...

son:

...

export default {
  inject: ['vm'], data(){}, mounted(){ console.log(this.vm) }

... 

Note: provide and inject bindings are not reactive. This was intentional. However, if you pass in a listenable object, then the properties of that object will still be listenable.

The value injected by inject will be searched upward along the component, following the "proximity principle".

The data flow in provide and inject is bidirectional.

5. eventBus

EventBus publishes and subscribes to global events for use by other components.

In main.js:

Vue.prototype.$bus = new Vue();

parent.vue:

<template>
  <div>
    <son1></son1>
    <son2></son2>
  </div>
</template>

<script>
import son1 from './son1.vue'
import son2 from './son2.vue'
export default {
  name: 'parent',
  components:
    son1,
    son2
  },
  created(){
     this.$bus.$on('busEvent',(v)=>{
      console.log(v);
    })
  },
  beforeDestroy(){
    this.$bus.off('busEvent')
  }
}
</script>

mounted in son1 and son2:

son1:mounted(){
  this.$bus.$emit('busEvent','son1哈哈')
}son2:mounted(){ this.$bus.$emit('busEvent', 'son2嘻嘻')}

Print results:

There are three points to note when using eventBus: 1. $bus.on should be used in the create hook. If it is used in mounted, it may not receive events sent by other components from the create hook;

2.$bus.emit should be used in mounted, waiting for the $bus.on event binding in create to complete;

3. The published subscribed events need to be released using $bus.off in the beforeDestory hook. There is no need to keep listening after the component is destroyed.

6. vuex

With the help of vuex's state management to achieve component communication, vuex is suitable for more complex projects, frequent data sharing and large amounts of data.

store/index.js:

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

const store = new Vuex.Store({
  state: {
    isLogin: false
  },
  mutations:
    loginState (state, isLogin) {
      state.isLogin = isLogin
    }
  }
})

export default store

App.vue:

created(){
  this.$store.commit('loginState',true)//Set login status to true
},

son.vue:

<template>
  <div>I am a son: <input type="button" value="son" />Login status: {{isLogin}}</div>
</template>

<script>
import {mapState} from 'vuex';
export default {
  name: "son",
  computed:{
    ...mapState(['isLogin'])
  }
};
</script> 

7. localstorage

localstorage is the local storage of the browser, which will be stored in the browser for a long time. It is not recommended to use this method for very large amounts of data.

App.vue

created(){
  localStorage.setItem('isLogin', true)
},

son.vue:

computed:{
  isLogin(){
    return localStorage.getItem('isLogin')
  }
}

These are basically the common component communication methods. If there are any omissions or deficiencies, please leave a message in the comment area!

Summarize

This is the end of this article about communication between vue components. For more relevant content about communication between vue components, please search previous articles on 123WORDPRESS.COM or continue to browse the following related articles. I hope you will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Details of 7 kinds of component communication in Vue3
  • Vue component communication method case summary
  • Eight examples of how Vue implements component communication
  • How does Vue implement communication between components?
  • How to implement parent-child component communication with Vue
  • Eight ways of component communication in Vue (worth collecting!)
  • Six ways of communication between Vue components (summary)
  • Several implementation methods of Vue component communication
  • Summary of communication methods between Vue components (parent-child components, sibling components, and ancestor-descendant components)
  • Several ways for Vue to achieve communication between components (multiple scenarios)

<<:  Detailed explanation of commands to view linux files

>>:  How to allow external network access to mysql and modify mysql account password

Recommend

Teach you how to monitor Tomcat's JVM memory through JConsoler

Table of contents 1. How to monitor Tomcat 2. Jav...

Using JavaScript difference to implement a comparison tool

Preface At work, I need to count the materials su...

HTML Basics Must-Read - Comprehensive Understanding of CSS Style Sheets

CSS (Cascading Style Sheet) is used to beautify H...

Solve the problem of IDEA configuring tomcat startup error

The following two errors were encountered when co...

Tutorial on how to install and use Ceph distributed software under Linux

Table of contents Preface 1. Basic Environment 1....

How to view the IP address of Linux in VMware virtual machine

1. First, double-click the vmware icon on the com...

Detailed explanation of the implementation of MySQL auto-increment primary key

Table of contents 1. Where is the self-incremente...

Zabbix3.4 method to monitor mongodb database status

Mongodb has a db.serverStatus() command, which ca...

Tutorial on installing Elasticsearch 7.6.2 in Docker

Install Docker You have to install Docker, no fur...

Shorten the page rendering time to make the page run faster

How to shorten the page rendering time on the bro...

How to delete all contents in a directory using Ansible

Students who use Ansible know that Ansible only s...

How to deploy Vue project using Docker image + nginx

1. Packaging Vue project Enter the following name...

Use CSS to set the width of INPUT in TD

Recently, when I was using C# to make a Web progra...