element icon indicating copy to clipboard operation
element copied to clipboard

[Bug Report] destroy-on-close in el-dialog will invoke inner component's created method

Open Duanzh opened this issue 4 years ago • 7 comments

Element UI version

2.13.0

OS/Browsers version

chrome

Vue version

2.6.11

Reproduction Link

https://codepen.io/duan1993/pen/eYNMdxZ

Steps to reproduce

  1. click "点击打开 Dialog" button, will alert(1)
  2. click "X" button, will alert(1) again

What is Expected?

when click "X" button, will not alert(1)

What is actually happening?

when click "X" button, will alert(1)

Duanzh avatar Mar 13 '20 02:03 Duanzh

Translation of this issue:

Element UI version

2.13.0

OS/Browsers version

Chrome

Vue version

2.6.11

Reproduction Link

https://codepen.io/duan1993/pen/eYNMdxZ

Steps to reproduce

  1. Click "click to open dialog" button, will alert (1)

  2. click "X" button, will alert(1) again

What is Expected?

when click "X" button, will not alert(1)

What is actually happening?

when click "X" button, will alert(1)

element-bot avatar Mar 13 '20 02:03 element-bot

This is because the el-dialog component uses a key attribute on a inner div which wraps the slot of your component. When you close a el-dialog with 'destroy-on-close' attribute set, the el-dialog just executes a 'key++' which causes your component rebuilding but not destory your component as we expect. Here is part of the source code of el-dialog and I cannot see why they are doing this:

if (this.destroyOnClose) {
    this.$nextTick(() => {
        this.key++;
    });
 }

veah avatar May 06 '20 06:05 veah

Any guesses how to destroy el-dialog properly (without 'mount' execute immediately after closing)?

mynameisseone avatar Jun 25 '20 14:06 mynameisseone

destory-on-close will cause high CPU and the page become unresponsive ...

towry avatar Dec 14 '20 06:12 towry

This does the work for me: I went inside the package and modify a few places, thank to @veah for pointing that out i add visibleWithDestroy and a v-if condition like so:

  data() {
    return {
      closed: false,
      // key: 0,
      visibleWithDestroy: true,
    }
  },
     ...
    <div
      v-show="visible"
      class="el-dialog__wrapper"
      @click.self="handleWrapperClick"
    >
      <div
        v-if="visibleWithDestroy"
        ref="dialog"
        role="dialog"
        aria-modal="true"
        :aria-label="title || 'dialog'"
        :class="[
          'el-dialog',
          { 'is-fullscreen': fullscreen, 'el-dialog--center': center },
          customClass,
        ]"
        :style="style"
      >
     ...

In the visible wacther i stopped using the original key method for destroying the inner dialog and use the new visibleWithDestroy instead

watch: {
  visible(val) {
    if (val) {
      this.visibleWithDestroy = true
      this.closed = false
      this.$emit('open')
      this.$el.addEventListener('scroll', this.updatePopper)
      this.$nextTick(() => {
        this.$refs.dialog.scrollTop = 0
      })
      if (this.appendToBody) {
        document.body.appendChild(this.$el)
      }
    } else {
      this.$el.removeEventListener('scroll', this.updatePopper)
      if (!this.closed) this.$emit('close')
      if (this.destroyOnClose) {
        this.$nextTick(() => {
          // this.key++
          this.visibleWithDestroy = false
        })
      }
    }
  },
},

imrim12 avatar Mar 12 '21 07:03 imrim12

same +1

if inner component has API call when it is created, that is too bad.

this Fix should be merged

Veitor avatar Jun 01 '21 02:06 Veitor

To anyone bumping into this weird bug in 2022 - A quick n easy DIY destroy-on-close : Just use v-if on the template your sending inside the el-dialog with the same property used to open it :)

DevOrish avatar Sep 20 '22 17:09 DevOrish

oh my god

meitingshuoguo avatar Oct 10 '22 03:10 meitingshuoguo

To anyone bumping into this weird bug in 2022 - A quick n easy DIY destroy-on-close : Just use v-if on the template your sending inside the el-dialog with the same property used to open it :)

thanks, that worked !! Yay!!

shaunie2fly avatar Nov 04 '22 00:11 shaunie2fly