今天花了一个晚上的时间,调试了一个功能。因为我需要一个比较复杂而且能够重用的dialog,也就是新建和编辑用同一个dialog,所以我把它拆分到了一个子组件中。这个dialog的隐藏和显示,就稍微有些麻烦了,而且官方的文章我也没有找到直接的操作方法,所以记录一下。
<el-button type="primary" @click="showDialog = true">添加</el-button>
<new-form :dialogVisible.sync="showDialog" ></new-form>
首先定义一个按钮,控制new-form组件的展示和隐藏,data里别忘了添加这个变量。
这里重点注意的是:.sync在element官方文档中,是直接写在dialog组件里的,这里我们拆分出来,后面再说为什么。
建立子组件,并包括一个dialog。
<template>
<el-dialog title="添加条目" :visible="dialogVisible" @close="onClose()">
<el-form :model="form">
// 这里加上表单的输入项目
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="onClose()">取 消</el-button>
<el-button type="primary" @click="onClose()">确 定</el-button>
</div>
</el-dialog>
</template>
关键点1: props子属性props:['dialogVisible'],
关键点2:
onClose(){
this.$emit('update:dialogVisible', false)
},
来源是vue文档
关键点3: 确定和取消以及dialog自带的关闭按钮被点击的时候,调用onclose,如果没有确定取消按钮,至少在dialog的close事件上一定要绑定。
从头梳理一下流程:父组件点击按钮=>传递值给子组件=>窗口展示。由于dialog被拆分到子组件,所以.sync语法糖被从dialog中提取到父组件中,确保当子组件dialog关闭,调用emit更新之后,父组件能够同步到最新的showDialog变量的值,然后传递给子组件,从而完成窗口隐藏。子组件关闭事件触发=>调用onClose函数=>emit传递给父组件最新的值=>父组件.sync语法糖触发=>父组件传递给子组件最新的值=>子组件完成dialog关闭。
我解决这个问题的关键在这个补充阅读
这里面还有一个疑惑,那就是dialog的close事件。如果我不绑定@close=”onClose()”,那么点击右上角的关闭按钮,无法关闭。如果我绑定了,那么当点击确定取消的时候,调用一次onClose,之后父组件会触发子组件的close事件,这个onClose还会被调用一次,就调用了两次。这个如果大家研究出了更好的方法,避免两次调用,希望能分享一下经验。
更新:其实加个简单的if判断就好了,如果visible=true,就emit事件。
PS:感谢评论区提供的意见,我实现了第二种版本,供大家参考。复杂度差不多,但是解藕方面更加清晰一些。
dialogVisible从props中移动到data中成为本地变量,created函数中加入
this.$on('open', function(){
this.dialogVisible = true
});
去掉子组件onClose函数,父组件修改为
<el-button type="primary" @click="open()">添加</el-button>
<new-form ref="form" ></new-form>
父组件添加函数
open(){
this.$refs.form.$emit("open")
}
如果有遗漏导致not working,我目前运行正常,大家在评论区留言。