Vuetify: [Feature Request] Add ability to listen for transition events on v-dialog

Created on 15 Feb 2019  路  9Comments  路  Source: vuetifyjs/vuetify

Problem to solve

Sometimes it is needed to run some code when v-dialog closes but do it only after closing animation ends, the problem is that at the moment there seems to be no way to determine when it ends.

Proposed solution

A possible solution would be to pass $listeners from v-dialog to the transition component. E.g.

if (this.transition) {
  dialog = h('transition', {
    on: this.$listeners,
    props: {
      name: this.transition,
      origin: this.origin
    }
  }, [dialog]);
}

So that it could be used like this:

<v-dialog v-model="isDialogActive" width="500" @after-leave="runSomeCode">
VDialog feature maybe

Most helpful comment

Any news on when there will be working transition hooks for v-dialog? I cannot get any of transitionend or after-enter to trigger. Thank you

All 9 comments

Use this function to patch the original component and forward the $listeners object.

import {VDialog as VDialogOriginal} from 'vuetify/lib';

/**
 * Hack to patch VDialog because it has no way to set transition hooks
 */
function patchVDialog (VDialog) {
  const ExtendedVDialog = VDialog.extend({});
  const originalRender = ExtendedVDialog.prototype.constructor.options.render;

  ExtendedVDialog.prototype.constructor.options.render = function (h) {
    const originalH = h;
    h = (...args) => {
      // Check for the call to render a transition,
      // there is only one rendered transition in VDialog
      if (args[0] === 'transition') {
        // Forward the user provided listeners to the transition component
        args[1].on = this.$listeners;
      }

      return originalH(...args);
    };
    return originalRender.call(this, h);
  };

  return ExtendedVDialog;
}

// This can be used now in place of the original.
const VDialog = patchVDialog(VDialogOriginal);

Any news on when there will be working transition hooks for v-dialog? I cannot get any of transitionend or after-enter to trigger. Thank you

Trying to figure out the status of this? Should it be working at this point or it's not implemented? I am not having any luck using transition callbacks on v-dialog.

In my case I need this functionality to properly set the width of an element that is part of the dialog content. It depends on the width of other elements in there, and I can't simply set it as soon as the dialog's model value changes because the content is not yet fully rendered as it is transitioning in.

I agree that this would be useful. I have the same use case as @flyingL123 with a SVG drawing that needs to be updated with the correct size. Currently I am doing this with a setTimeout, but this is a bit ugly.

Temporary solution:
v-snackbar

watch: {
  value(newValue, oldValue) {
    if (!newValue && oldValue) {
      snackbarEl.addEventListener('transitionend', () => {
        // code
      }, { once: true });
    }
  },
}

v-dialog

setTimeout(() => {
  // code
}, 300);

Use this function to patch the original component and forward the $listeners object.

import {VDialog as VDialogOriginal} from 'vuetify/lib';

/**
 * Hack to patch VDialog because it has no way to set transition hooks
 */
function patchVDialog (VDialog) {
  const ExtendedVDialog = VDialog.extend({});
  const originalRender = ExtendedVDialog.prototype.constructor.options.render;

  ExtendedVDialog.prototype.constructor.options.render = function (h) {
    const originalH = h;
    h = (...args) => {
      // Check for the call to render a transition,
      // there is only one rendered transition in VDialog
      if (args[0] === 'transition') {
        // Forward the user provided listeners to the transition component
        args[1].on = this.$listeners;
      }

      return originalH(...args);
    };
    return originalRender.call(this, h);
  };

  return ExtendedVDialog;
}

// This can be used now in place of the original.
const VDialog = patchVDialog(VDialogOriginal);

@b-strauss Can you give a complete example of using this hack?

@gustavosbarreto

you need to include the patched VDialog to use inside your template

const VDialog = patchVDialog(VDialogOriginal);

export default {
  components: {
    VDialog,
  },
};

Then in the template just add your listeners to the patched component.

<v-dialog @after-enter=""></v-dialog>
Was this page helpful?
0 / 5 - 0 ratings