简体   繁体   中英

Await a grandparent component's method to be resolved in grandchild component

I have three components in my vue application:

  • Home: (Button's grandparent)
  • Dialog: (Home's child / Button's parent)
  • Button: (Home's grandchild)

The Home component has a async method:

async handleDialogAccept() {
  try {
    const response = await this.$axios.get('https://jsonplaceholder.typicode.com/todos/');
    console.log(response.data);
  } catch (err) {
    console.log(err);
  }
},

And it will executed as soon as the Dialog component emits the "accept" custom event:

<dialog-confirmation
  @accept="handleDialogAccept()"
/>

The Dialog component has a child ( Button ):

<button-accept
  v-on="$listeners"
>
  Accept
</button-accept>

In my buttonAccept.vue which is being imported in the Dialog and used as shown above has the next structure:

<template>
  <v-btn
    color="primary"
    @click="handleClick()"
    :loading="loading"
    :disabled="loading"
  >
    <slot name="accept"></slot>
  </v-btn>
</template>

<script>
export default {
  props: ['parentFunction'],
  data() {
    return {
      loading: false,
    };
  },
  methods: {
    handleClick() {
      this.$emit('accept');
    },
  },
};
</script>

I will like to execute the next steps inside the handleClick method:

  1. Set loading to true
  2. Emit the accept custom event
  3. Wait until the handleDialogAccept is done
  4. Set loading to false

Is there a wait to do so?

Maybe, you can define a variable ( isAcceptDone ) in Home component to determine whether the async method is done or not in the Button component.

The Home component

async handleDialogAccept() {
  try {
    const response = await this.$axios.get('https://jsonplaceholder.typicode.com/todos/');
    console.log(response.data);
    this.isAcceptDone = true;
  } catch (err) {
    console.log(err);
  }
},

The Dialog component

<dialog-confirmation
  @accept="handleDialogAccept()"
  :isAcceptDone="isAcceptDone"
/>

The Button component

<script>
  export default {
    props: ['parentFunction', 'isAcceptDone'],
    data() {
      return {
        loading: false,
      };
    },
    watch: {
      isAcceptDone(val) {
         if(val) {
           this.loading = false
         }
      }
    },
    methods: {
      handleClick() {
        this.$emit('accept');
      },
    }
 };
</script>

On the other hand, If you thought it is too complicated to pass isAcceptDone in three components. Using EventBus is another simple ways.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM