Просмотр исходного кода

Dialog: add destroyOnClose attribute (#16455)

* Dialog: add destroyOnClose attribute

* update
hetech 6 лет назад
Родитель
Сommit
d238c768a6

+ 1 - 0
examples/docs/en-US/dialog.md

@@ -221,6 +221,7 @@ If the variable bound to `visible` is managed in Vuex store, the `.sync` can not
 | show-close | whether to show a close button | boolean    | — | true |
 | before-close | callback before Dialog closes, and it will prevent Dialog from closing | function(done),done is used to close the Dialog | — | — |
 | center | whether to align the header and footer in center | boolean | — | false |
+| destroy-on-close | Destroy elements in Dialog when closed   | boolean | — | false |
 
 ### Slot
 

+ 1 - 0
examples/docs/es/dialog.md

@@ -229,6 +229,7 @@ Si la variable ligada a `visible` se gestiona en el Vuex store, el `.sync` no pu
 | show-close            | si mostrar un botón de cerrar            | boolean                                  | —                 | true        |
 | before-close          | una devolución de llamada antes de que se cierre el cuadro de diálogo, y evitar cerrar el cuadro de diálogo | función(done) `done`se usa para cerrar el diálog | —                 | —           |
 | center                | si alinear el encabezado y el pie de página en el centro | boolean                                  | —                 | false       |
+| destroy-on-close      | Destroy elements in Dialog when closed   | boolean                                  | —                 | false         |
 
 ### Slots
 

+ 1 - 0
examples/docs/fr-FR/dialog.md

@@ -224,6 +224,7 @@ Si la variable liée à `visible` est gérée dans Vuex, le modificateur `.sync`
 | show-close | Si le bouton de fermeture doit apparaître. | boolean    | — | true |
 | before-close | Callback avant la fermeture du Dialog. | function(done),done est utilisé pour fermer le Dialog. | — | — |
 | center | Si le header et le footer doivent être centrés. | boolean | — | false |
+| destroy-on-close | Destroy elements in Dialog when closed   | boolean | — | false |
 
 ### Slot
 

+ 1 - 0
examples/docs/zh-CN/dialog.md

@@ -219,6 +219,7 @@ Dialog 的内容是懒渲染的,即在第一次被打开之前,传入的默
 | show-close | 是否显示关闭按钮 | boolean    | — | true |
 | before-close | 关闭前的回调,会暂停 Dialog 的关闭 | function(done),done 用于关闭 Dialog | — | — |
 | center | 是否对头部和底部采用居中布局 | boolean | — | false |
+| destroy-on-close | 关闭时销毁 Dialog 中的元素 | boolean | — | false |
 
 ### Slot
 | name | 说明 |

+ 16 - 5
packages/dialog/src/component.vue

@@ -3,13 +3,16 @@
     name="dialog-fade"
     @after-enter="afterEnter"
     @after-leave="afterLeave">
-    <div class="el-dialog__wrapper" v-show="visible" @click.self="handleWrapperClick">
+    <div
+      v-show="visible"
+      class="el-dialog__wrapper"
+      @click.self="handleWrapperClick">
       <div
         role="dialog"
+        :key="key"
         aria-modal="true"
         :aria-label="title || 'dialog'"
-        class="el-dialog"
-        :class="[{ 'is-fullscreen': fullscreen, 'el-dialog--center': center }, customClass]"
+        :class="['el-dialog', { 'is-fullscreen': fullscreen, 'el-dialog--center': center }, customClass]"
         ref="dialog"
         :style="style">
         <div class="el-dialog__header">
@@ -102,12 +105,15 @@
       center: {
         type: Boolean,
         default: false
-      }
+      },
+
+      destroyOnClose: Boolean
     },
 
     data() {
       return {
-        closed: false
+        closed: false,
+        key: 0
       };
     },
 
@@ -126,6 +132,11 @@
         } else {
           this.$el.removeEventListener('scroll', this.updatePopper);
           if (!this.closed) this.$emit('close');
+          if (this.destroyOnClose) {
+            this.$nextTick(() => {
+              this.key++;
+            });
+          }
         }
       }
     },

+ 28 - 1
test/unit/specs/dialog.spec.js

@@ -1,4 +1,4 @@
-import { createVue, destroyVM } from '../util';
+import { createVue, destroyVM, waitImmediate } from '../util';
 
 describe('Dialog', () => {
   let vm;
@@ -289,4 +289,31 @@ describe('Dialog', () => {
       }, 500);
     }, 10);
   });
+
+  it('destroyOnClose', async() => {
+    vm = createVue({
+      template: `
+        <div>
+          <el-dialog :title="title" :visible.sync="visible" destroy-on-close>
+            <input />
+          </el-dialog>
+        </div>
+      `,
+
+      data() {
+        return {
+          title: 'dialog test',
+          visible: true
+        };
+      }
+    }, true);
+    const dialog = vm.$children[0];
+    await waitImmediate();
+    dialog.$el.querySelector('input').value = '123';
+    dialog.$el.click();
+    await waitImmediate();
+    vm.visible = true;
+    await waitImmediate();
+    expect(dialog.$el.querySelector('input').value).to.be.equal('');
+  });
 });

+ 3 - 0
types/dialog.d.ts

@@ -55,5 +55,8 @@ export declare class ElDialog extends ElementUIComponent {
   /** Whether to align the header and footer in center */
   center: boolean
 
+  /** Whether to destroy elements in Dialog when closed */
+  destroyOnClose: boolean
+
   $slots: DialogSlots
 }