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 关闭回调函数来更新父组件状态。

相关推荐
来自星星的坤4 小时前
Vue 3中如何封装API请求:提升开发效率的最佳实践
前端·javascript·vue.js
vvilkim6 小时前
全面解析React内存泄漏:原因、解决方案与最佳实践
前端·javascript·react.js
vvilkim6 小时前
React批处理(Batching)更新机制深度解析
前端·javascript·react.js
Bayi·6 小时前
前端面试场景题
开发语言·前端·javascript
程序猿熊跃晖7 小时前
Vue中如何优雅地处理 `<el-dialog>` 的关闭事件
前端·javascript·vue.js
进取星辰7 小时前
12、高阶组件:魔法增幅器——React 19 HOC模式
前端·javascript·react.js
拉不动的猪7 小时前
前端低代码开发
前端·javascript·面试
程序员张37 小时前
Vue3集成sass
前端·css·sass
夜跑者7 小时前
axios 在请求拦截器中设置Content-Type无效问题
前端
知识分享小能手7 小时前
JavaScript学习教程,从入门到精通,Ajax与Node.js Web服务器开发全面指南(24)
开发语言·前端·javascript·学习·ajax·node.js·html5