background

Now let’s talk about a situation where the parent communicates with the grandchild. How many solutions do we have?

  1. We use VueX for data management, but if there is less shared state among multiple components in a project, the project is small, and there is less global state, then using VueX for this functionality is not the full power of VueX.
  2. B is used as A transfer station. When A component needs to transmit information to C component, B accepts the information of A component and then uses attributes to transmit it to C component. This is A solution, but if there are too many nested components, it will lead to cumbersome code and difficult code maintenance. If A state change in C needs to be passed to A, use the event system to pass it up one level.
  3. A custom Vue central data bus is suitable for cross-level messaging of components, but the disadvantage is low maintenance and low readability of code in multi-party cooperation

I. Document description

(1) $props: The props object received by the current component. The Vue instance proxies access to properties of its props object.

$attrs: contains feature bindings (except class and style) that are not recognized (and retrieved) as prop in the parent scope.

$listeners include V-ON event listeners in the parent scope (without.native modifiers). Internal components can be passed on via V-on =”listeners”

Two, specific use

1. Parent component

<template>
  <div>
    <div>Father components</div>
    <Child
      :foo="foo"
      :zoo="zoo"
      @handle="handleFun"
    >
    </Child>
  </div>
</template>

<script>
import Child from './Child.vue'
export default {
  components: { Child },
  data() {
    return {
      foo: 'foo'.zoo: 'zoo'}},methods: {
    // Pass events
    handleFun(value) {
      this.zoo = value
      console.log('Sun Tzu component hit event, I received it')}}}</script>
Copy the code

2. Child Component (child.vue)

The middle tier, which acts as a pass-through between the parent and the grandchild, adds v-bind=”$attrs” to the grandchild so that the grandchild can receive data.

$attrs is data passed in from the parent and not received by the child, such as zoo

<template>
  <div class='child-view'>
    <p>The son component --{{$props. Foo}} has the same content as {{foo}}</p>
    <GrandChild v-bind="$attrs" v-on="$listeners"></GrandChild>
  </div>
</template>

<script>
import GrandChild from './GrandChild.vue'
export default {
  // Inherits the contents of all parent components
  inheritAttrs: true.components: { GrandChild },
  props: ['foo'].data() {
    return{}}}</script>
Copy the code

3. Grandchild.vue

Be sure to use props in the grandson component to receive data from the parent component

<template>
  <div class='grand-child-view'>
    <p>The grandson components</p>
    <p>Data passed to grandchild component: {{zoo}}</p>
    <button @click="testFun">Click me to trigger the event</button>
  </div>
</template>

<script>
export default {
  // Do not want to inherit all of the parent component's content, and do not display attributes on the component root element DOM
  inheritAttrs: false.// This component needs to receive data from the parent component. Make sure that the parameter names in props are the same as those passed by the parent component
  props: ['zoo'].methods: {
    testFun() {
      this.$emit('handle'.'123')}}}</script>
Copy the code

Third, summary

Use the inheritAttrs attribute to pass data from component A to component C using concise code.

Notice We are attaching V-on = “$Listeners” to COMPONENT B and listening for events triggered by component C on component A. I can pass the data from component C to component A.