7

今天花了一个晚上的时间,调试了一个功能。因为我需要一个比较复杂而且能够重用的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,我目前运行正常,大家在评论区留言。


敲键盘的猫
772 声望131 粉丝

一只热爱科技的猫