element-ui dialog form 弹框表单组件封装

在使用 element-ui 进行后端管理系统开发时,在封装弹框表单时,遇到两个问题,这里进行简单记录:

1、问题一:点击关闭按钮及遮罩层关闭弹框时,页面报错,如下:

子组件封装:

html 复制代码
<template>
  <el-dialog title="dialog form" :visible.sync="visible" width="432px">
    <el-form ref="formRef" :model="form">
      <el-form-item label="姓名" prop="username">
        <el-input placeholder="请输入姓名" v-model="form.username"> </el-input>
      </el-form-item>
    </el-form>
    <div slot="footer" class="dialog-footer">
      <el-button @click="handleCancel">取消</el-button>
      <el-button type="primary" @click="handleSubmit">提交</el-button>
    </div>
  </el-dialog>
</template>

<script>
export default {
  name: 'DialogForm',
  props: {
    visible: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      form: {
        username: ''
      }
    };
  },
  methods: {
    // 关闭弹框
    handleCancel() {
      this.$emit('update:visible', false);
    },

    // 提交
    handleSubmit() {
      this.$refs.formRef.validate((valid) => {
        if (valid) {
          console.log('this.form::', this.form);
          this.handleCancel();
        } else {
          console.log('error submit!!');
          return false;
        }
      });
    }
  }
};
</script>

父组件使用:

html 复制代码
<template>
  <div>
    <el-button type="primary" @click="handleOpen">dialog form</el-button>
    <!-- 弹框表单-->
    <dialog-form :visible.sync="visible"></dialog-form>
  </div>
</template>

<script>
import DialogForm from './DialogForm.vue';

export default {
  name: 'Header',
  components: { DialogForm },
  data() {
    return {
      visible: false
    };
  },
  methods: {
    handleOpen() {
      this.visible = true;
    }
  }
};
</script>

解决之后,父组件代码不变,子组件代码修改如下:

html 复制代码
<template>
  <el-dialog title="dialog form" :visible.sync="dialogVisible" width="432px">
    <el-form ref="formRef" :model="form">
      <el-form-item label="姓名" prop="username">
        <el-input placeholder="请输入姓名" v-model="form.username"> </el-input>
      </el-form-item>
    </el-form>
    <div slot="footer" class="dialog-footer">
      <el-button @click="handleCancel">取消</el-button>
      <el-button type="primary" @click="handleSubmit">提交</el-button>
    </div>
  </el-dialog>
</template>

<script>
export default {
  name: 'DialogForm',
  props: {
    visible: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      dialogVisible: this.visible,
      form: {
        username: ''
      }
    };
  },
  watch: {
    visible(newVal) {
      this.dialogVisible = newVal;
    }
  },
  methods: {
    // 关闭弹框
    handleCancel() {
      this.dialogVisible = false;
      this.$emit('update:visible', this.dialogVisible);
    },

    // 提交
    handleSubmit() {
      this.$refs.formRef.validate((valid) => {
        if (valid) {
          console.log('this.form::', this.form);
          this.handleCancel();
        } else {
          console.log('error submit!!');
          return false;
        }
      });
    }
  }
};
</script>

产生原因,子组件通过 update 的方式直接修改了 props 传递的属性,解决方法,在子组件中使用一个变量 dialogVisible 接收父组件传递过来的 props 属性 visible,子组件内部 dialog 通过 dialogVisible 这个变量来控制。

2、问题二:点击关闭按钮和遮罩层关闭弹框之后,再次进行打开弹框时,弹框未打开,页面未报错,如下:

父组件代码保持不变,子组件代码修改如下:

html 复制代码
<template>
  <el-dialog
    title="dialog form"
    :visible.sync="dialogVisible"
    width="432px"
    @close="handleClose"
  >
    <el-form ref="formRef" :model="form">
      <el-form-item label="姓名" prop="username">
        <el-input placeholder="请输入姓名" v-model="form.username"> </el-input>
      </el-form-item>
    </el-form>
    <div slot="footer" class="dialog-footer">
      <el-button @click="handleCancel">取消</el-button>
      <el-button type="primary" @click="handleSubmit">提交</el-button>
    </div>
  </el-dialog>
</template>

<script>
export default {
  name: 'DialogForm',
  props: {
    visible: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      dialogVisible: this.visible,
      form: {
        username: ''
      }
    };
  },
  watch: {
    visible(newVal) {
      this.dialogVisible = newVal;
    }
  },
  methods: {
    // 弹框关闭的回调
    handleClose() {
      this.handleCancel();
    },

    // 关闭弹框
    handleCancel() {
      this.dialogVisible = false;
      this.$emit('update:visible', this.dialogVisible);
    },

    // 提交
    handleSubmit() {
      this.$refs.formRef.validate((valid) => {
        if (valid) {
          console.log('this.form::', this.form);
          this.handleCancel();
        } else {
          console.log('error submit!!');
          return false;
        }
      });
    }
  }
};
</script>

产生原因,在点击关闭图标和遮罩层关闭时,子组件未更新父组件的 visible 状态,解决方法,在子组件内通过 close 方法,即 dialog 关闭回调函数来更新父组件状态。

相关推荐
xiao-xiang4 分钟前
jenkins-通过api获取所有job及最新build信息
前端·servlet·jenkins
C语言魔术师20 分钟前
【小游戏篇】三子棋游戏
前端·算法·游戏
匹马夕阳2 小时前
Vue 3中导航守卫(Navigation Guard)结合Axios实现token认证机制
前端·javascript·vue.js
你熬夜了吗?2 小时前
日历热力图,月度数据可视化图表(日活跃图、格子图)vue组件
前端·vue.js·信息可视化
桂月二二8 小时前
探索前端开发中的 Web Vitals —— 提升用户体验的关键技术
前端·ux
沈梦研9 小时前
【Vscode】Vscode不能执行vue脚本的原因及解决方法
ide·vue.js·vscode
hunter2062069 小时前
ubuntu向一个pc主机通过web发送数据,pc端通过工具直接查看收到的数据
linux·前端·ubuntu
qzhqbb9 小时前
web服务器 网站部署的架构
服务器·前端·架构
刻刻帝的海角9 小时前
CSS 颜色
前端·css
轻口味9 小时前
Vue.js 组件之间的通信模式
vue.js