element-ui中el-dialog组件之destroy-on-close属性

一. :destroy-on-close="true"的场景

有一种场景是我们有一个新建按钮,要求每次我们重新打开el-dialog都是干净的内容,所以我们每次点击按钮可能会用以下几种办法。

(1) 对使用的data数据进行重置

(2) 直接对包裹内容区域的dom(组件)使用v-if,销毁/重建dom节点(组件)

(3) 使用:destroy-on-close="true",

但问题是输入value值后,再重新打开内容还是存在。

<template>
  <div class="hello">
      <el-dialog
        title="弹框"
        :visible.sync="dialogVisible"
        :destroy-on-close="true"
        >
        <div>
          dialog
          <el-input v-model="value" placeholder="输入测试的数据"></el-input>
        </div>
        <div slot="footer">
          <el-button @click="dialogVisible = false">取 消</el-button>
          <el-button type="primary" @click="dialogVisible = false">确 定</el-button>
        </div>
      </el-dialog>
      <el-button @click="showDialog">点击</el-button>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  },
  data () {
    return {
       dialogVisible: true,
       value: '',
    }
  },
  methods: {
    showDialog () {
       this.dialogVisible = !this.dialogVisible
    }
  }
}
</script>


二 . 问题研究

  1. destroy-on-close="true",文档说关闭时销毁 Dialog 中的元素

  2. 由源码得到该属性会让class为el-dialog的dom节点重新生成。

    (注意:key 的特殊 attribute 主要用在 Vue 的虚拟 DOM 算法,在新旧 nodes 对比时辨识 VNodes。如果不使用 key,Vue 会使用一种最大限度减少动态元素并且尽可能的尝试就地修改/复用相同类型元素的算法。而使用 key 时,它会基于 key 的变化重新排列元素顺序,并且会移除 key 不存在的元素。)

    // html部分    
    <div
            role="dialog"
            :key="key"
            aria-modal="true"
            :aria-label="title || 'dialog'"
            :class="['el-dialog', { 'is-fullscreen': fullscreen, 'el-dialog--center': center }, customClass]"
            ref="dialog"
            :style="style">...
    // js 部分
     watch: {
          visible(val) {
            if (val) { 
              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(() => { //重新生成class为el-dialog的dom
                  this.key++;
                });
              }
            }
          }
        },
    

三 . 怎么使用这个特点

所以你在当前组件使用时,声明数据全都在my-content组件中,这样当my-content被销毁的时候属于my-content的数据才会一起被销毁

<template>
    <el-dialog>
       <my-content></my-content>
    </el-dialog>
</template>
posted @ 2021-11-28 23:36  这样就好了  阅读(4964)  评论(0编辑  收藏  举报