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

MySQL sql_mode analysis and setting explanation

When inserting a set of data into the MySQL datab...

Detailed steps for installing rockerChat in docker and setting up a chat room

Comprehensive Documentation github address https:...

React implements the expansion and collapse function of complex search forms

Give time time and let the past go. In the previo...

mysql IS NULL using index case explanation

Introduction The use of is null, is not null, and...

Nodejs-cluster module knowledge points summary and example usage

The interviewer will sometimes ask you, tell me h...

Notes on MySQL case sensitivity

Table of contents MySQL case sensitivity is contr...

Docker completely deletes private library images

First, let’s take a look at the general practices...

Detailed explanation of important cascading concepts in CSS

Recently, I encountered a problem in the process ...

Steps to install GRUB on Linux server

How to Install GRUB for Linux Server You cannot u...

How to reduce the memory and CPU usage of web pages

<br />Some web pages may not look large but ...

Summary of various postures of MySQL privilege escalation

Table of contents 1. Write Webshell into outfile ...

Causes and solutions for MySQL deadlock

The database, like the operating system, is a sha...

How to use union all in MySQL to get the union sort

Sometimes in a project, due to some irreversible ...