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