theme: smartblue
这是我参与11月更文挑战的第3天,活动详情查看:2021最后一次更文挑战
问题
之前在项目中使用了elementUI的组件库,它有个Dialog对话框组件,对话框里面的内容是会缓存的,每次切换显示Dialog并不会重新渲染对话框的内容。
我们一般会在Dialog组件嵌套表单,如果你在表单上有编辑的话,关闭Dialog后再次打开Dialog,表单还是上次编辑的内容,并没有清空。
如果我们想每次打开都重新清空表单,那么该怎么办?
destroy-on-close属性
然后我就去翻官方文档,翻阿翻,翻阿翻,终于找到了有个属性, destroy-on-close
。
这个属性就是说在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
}
}
}
可以看到我在输入框输入了答案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