Communicate via the setup() function

In Vue3,$on is removed and the setup function this points to undefined, not to the Vue instance object. Therefore, parent/child communication is not possible using the this.$emit() method in Vue2. However, parent/child communication is possible using the second parameter in the setup function.

  • The setup function takes two arguments, the first parameter being props and the second parameter being an object context
  • The props object contains all prop data passed by the parent component. The Context object contains the attrs, slots, and EMIT properties, where the emit can trigger the execution of custom events to complete the parent
// Code implementation:

// In the parent component
<template>
  <son :name="name" @get-msg="getMsg"></son>
</template>
<script>
import { ref } from 'vue'
import Son from './components/son'
export default {
  components: {
    Son
  },
  setup() {
    const name = ref('cp')
    function getMsg(msg) { // The child component fires a custom event that receives a value
      console.log(msg)
    }
    return {
      name,
      getMsg
    }
  }
}
</script>

// Subcomponent:
<template>
  <div>
    {{name}}
    <button @click="setMsgToSon">set</button>
  </div>
</template>

<script>
export default {
  props: {
    name: {
      type: String}},emits: ['get-msg'].// Declare a custom event triggered by the current component
  setup(props,{emit}) {
    console.log(props.name)
    function setMsgToSon(){
      emit('get-msg'.'This is a MSG message from a child component')}return {
      setMsgToSon
    }
  }
}
</script>
Copy the code

Communicate with provide and Inject

Use props for data transfer between parent and child. If the nested layer of components is deep, layer by layer transmission becomes very tedious. Provide and Inject can facilitate data transfer across layers by combining them

Provide and Inject are both methods in vue instances

// Upper-layer components
<template>
  <father></father>
</template>

<script>
import Father from '@/components/Father'
import { provide } from 'vue'// Introduce provide in the upper component
export default {
  components: {
    Father
  },
  setup() {
    let name = 'Joe'
    // Inject key-value data using the provide configuration item
    provide('name', name)
  }
}
</script> 
Copy the code
// Lower layer child or grandchild<template> I am descendant component {{name}}// Run the following command
</template>

<script>
import { inject } from 'vue' // Reference the Inject method in the descendant component
export default {
  setup() {
    const name = inject('name')
    return {
      name
    }
  }
}
</script>
Copy the code

As long as it is a descendant component, it can easily obtain the data provided by the top-level component

By default, the data transferred by provide is not reactive, that is, if the data provided by provide is modified, it cannot affect the use of data by underlying components in a reactive manner. If you want to transfer the response data, you only need to use REF or Reactive to generate the passed data

<template>
  <son></son>
  <button @click="changeName">change name</button>
</template>

<script>
import Son from '@/components/Son'
import { provide, ref } from 'vue'
export default {
  components: {
    Son
  },
  setup() {
    // use ref to convert to response and pass
    let name = ref('Joe')
    function changeName(){
      name.value = 'bill'
    }
    provide('name', name)
    return {
      changeName
    }
  }
}
</script> 
Copy the code