使用Dialog组件的destroy-on-close属性__JavaScript__Vue.js
发布于 3 年前 作者 banyungong 1980 次浏览 来自 分享
粉丝福利 : 关注VUE中文社区公众号,回复视频领取粉丝福利

theme: smartblue

这是我参与11月更文挑战的第3天,活动详情查看:2021最后一次更文挑战

问题

之前在项目中使用了elementUI组件库,它有个Dialog对话框组件,对话框里面的内容是会缓存的,每次切换显示Dialog并不会重新渲染对话框的内容。

我们一般会在Dialog组件嵌套表单,如果你在表单上有编辑的话,关闭Dialog后再次打开Dialog,表单还是上次编辑的内容,并没有清空。

如果我们想每次打开都重新清空表单,那么该怎么办?

GIF 2021-11-3 19-49-26.gif

destroy-on-close属性

然后我就去翻官方文档,翻阿翻,翻阿翻,终于找到了有个属性, destroy-on-close

image.png

这个属性就是说在Dialog关闭的时候可以把元素清除,这样不就满足我们的要求了吗?下次打开的时候重新渲染,那样表单填的数据就也会被清空掉。

于是我就在项目中使用了这个属性,但是它竟然没有生效。

<el-button @click="toggleDialog(true)">显示dialog</el-button>
<el-dialog title="提示" :visible.sync="dialogVisible" width="30%" :destroy-on-close="true">
  <el-input v-model="inputVal"></el-input>
  <span slot="footer" class="dialog-footer">
    <el-button @click="dialogVisible = false">取 消</el-button>
    <el-button type="primary" @click="dialogVisible = false">确 定</el-button>
  </span>
</el-dialog>
export default {
  data () {
    return {
      inputVal: '',
      dialogVisible: false
    }
  },
  methods: {
    toggleDialog (status) {
      this.dialogVisible = status
    }
  }
}

GIF 2021-11-3 19-49-26.gif

可以看到我在输入框输入了答案cp3,然后我关闭Dialog后再打开并没有清空表单的内容。

这个属性没有生效,难道是这个组件有bug?

百思不得其解,然后我就去官方的组件库看源码,果不其然,有答案了。

截取部分代码:

<!--注意它有个key-->
<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">
  ...省略
</div>
if (this.destroyOnClose) {
    this.$nextTick(() => {
      this.key++;
    });
}

可以看到这个Dialog组件是用destroyOnClose属性来控制key的属性。当key属性变化的时候,vue会对当前组件重新渲染。

因为我的input组件的value是定义在dialog的父组件里面的,并不是在它当前组件里定义的,所以重新渲染是没有效果的,并不能把表单清空。

所以要使用这个属性的时候,并不能在dialog的父组件定义value,需要你创建一个组件,传入dialog中,数据都是在这个组件中定义,再传给dialog的父组件(单向数据流,子到父)。

另外补充一下,这个属性并不是销毁 Dialog 中的元素, 而是重新渲染,包括它的生命周期函数也会重新执行。

这个属性慎用~

版权声明:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 作者: 答案cp3 原文链接:https://juejin.im/post/7026342555310637070

回到顶部