封装组件库-弹出框表单
2023, Mar 07
实现弹出框表单的封装
基于Element-plus框架的Dialog对话框组件和封装的Form表单组件进行封装。
初始配置
- 注册路由组件modalForm,配置为Container组件的子路由组件
- 采用路由懒加载,箭头函数异步引入组件。
- 注册通用组件modalForm,为路由组件的子组件,以便组件间通信。
- 将通用组件modalForm注册为全局组件
实现弹出框的基本框架
- 子组件基本结构
<div :class="{'choose-icon-dialog-body-height':isScroll}">
<el-dialog
v-model='dialogVisible'
v-bind="$attrs ">
<template #default>
</template>
</el-dialog>
</div>
let emits = defineEmits(['update:visible'])
let props = defineProps({
visible:{
type: Boolean,
default: false
}
}
let dialogVisible = ref<boolean>(props.visible)
watch(()=>props.visible,val=>{
dialogVisible.value = props.visible
})
watch(()=>dialogVisible.value,val=>{
emits('update:visible',val)
})
- 父组件基本结构
<el-button type="primary" @click="open" >open</el-button>
<my-modal-form v-model:visible="visible"
:options="options"
title="编辑用户"
width="50%"
isScroll >
<template #footer="{form}">
<el-button @click="cancel(form)">取消</el-button>
<el-button type="primary" @click="confirm(form)">确认</el-button>
</template>
//显示上传组件
<template #uploadArea>
<el-button type="primary" size="small">Click to upload</el-button>
</template>
<template #uploadTip>
<div style="color: #ccc;font-size:12px; margin-left:10px">
jpg/png files with a size less than 500KB.
</div>
</template>
</my-modal-form>
let visible = ref<boolean>(false)
let open = ()=>{
visible.value = true
}
- 父组件表单配置项
let options: FormOptions[] =[
{
type: 'input',
value: '',
label: '用户名',
placeholder: '请输入用户名',
prop: 'username',
rule: [
{
required: true,
message: '用户名不能为空',
trigger: 'blur'
},
{
min: 2,
max: 6,
message: '用户名在2-6位之间',
trigger: 'blur'
}
],
attrs: {
clearable: true
}
},
{
type: 'input',
value: '',
label: '密码',
placeholder: '请输入密码',
prop: 'password',
rule: [
{
required: true,
message: '密码不能为空',
trigger: 'blur'
},
{
min: 6,
max: 15,
message: '密码在6-15位之间',
trigger: 'blur'
}
],
attrs: {
showPassword: true,
clearable: true
}
},
{
type: 'select',
value: '',
label: '职位',
placeholder: '请选择职位',
prop: 'role',
attrs: {
style: {width:'100%'}
},
rule:[
{
required: true,
message: '职位不能为空',
trigger: 'change'
}
],
children: [
{
type: 'option',
label: '经理',
value: '1',
prop: 'jingli'
},
{
type: 'option',
label: '主管',
value: '2',
prop: 'zhuguan'
},
{
type: 'option',
label: '员工',
value: '3',
prop: 'yuangong'
}
]
},
{
type: 'checkbox-group',
value: [],
prop: 'aihao',
label: '爱好',
rule: [
{
required: true,
message: '爱好不能为空',
trigger: 'change'
}
],
children:[
{
type: 'checkbox',
value: '1',
prop: 'zuqiu',
label: '足球'
},
{
type: 'checkbox',
value: '2',
prop: 'paiqiu',
label: '排球'
},
{
type: 'checkbox',
value: '3',
prop: 'pingpangqiu',
label: '乒乓球'
}
]
},
{
type: 'radio-group',
value: '',
prop: 'gender',
label: '性别',
rule: [
{
required: true,
message: '性别不能为空',
trigger: 'blur'
}
],
children:[
{
type: 'radio',
value: 'male',
prop: 'male',
label: '男'
},
{
type: 'radio',
value: 'female',
prop: 'female',
label: '女'
},
{
type: 'radio',
value: 'not',
prop: 'baomi',
label: '保密'
}
]
},
{
type: 'upload',
prop: 'pic',
label: '上传',
uploadAttrs:{
action: 'https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15',
multiple: true,
limit: 3
},
rule: [
{
required: true,
message: '图片不能为空',
trigger: 'blur'
}
],
},
{
type: 'editor',
value: '',
prop: 'desc',
label: '描述',
placeholder: '请输入描述',
rule:[
{
required: true,
message: '描述不能为空',
trigger: 'blur'
}
]
}
]
- 表单验证方法: form子组件通过方法定义将表单验证和表单数据分发给父组件。
//表单验证
let validate = ()=>{
return form.value!.validate
}
//获取表单数据
let getFormData = ()=>{
return model.value
}
//分发方法,不能直接分发model,只能拿到初始值
defineExpose({
resetFields,
validate,
getFormData
})
<!-- 基于拿到的方法进行表单验证 -->
<template #footer>
<slot name="footer" :form="form"></slot>
</template>
let confirm = (form: any)=>{
//表单验证的方法,返回值才是方法
let validate = form.validate()
let model = form.getFormData()
validate((valid: any)=>{
if(valid){
ElMessage.success('验证成功')
console.log(model);
}else{
ElMessage.error('验证失败')
}
})
}
- 重置
let cancel = (form: any)=>{
visible.value = false
form.resetFields()
}