记录一下最近封装的组件,之前有二次封装过这个组件但是后来需求更新的比较多导致组件比较乱,趁着这次的新项目重新封装了一个
<template>
<div class="layout-padding">
<div class="layout-padding-auto layout-padding-view">
<el-row class="ml10" v-show="showSearch">
<c-form
:model="formField"
:inline="true"
:form-data="formData"
:form-field="formField"
:tools-config="{
leftBtnS: [
{
text: '新增',
onClick: () => {
dialogVisible = true;
},
auths: ['merchant_export'],
},
],
rightBtnS: [
{
text: '搜索',
onClick: getDataList,
},
{
text: '重置',
onClick: resetQuery,
type: 'default',
},
],
}"
/>
</el-row>
<c-table
:data="state.dataList"
@selection-change="handleSelectionChange"
style="width: 100%"
row-key="postId"
border
:cell-style="tableStyle?.cellStyle"
:header-cell-style="tableStyle?.headerCellStyle"
:columns="columns"
/>
<pagination @current-change="currentChangeHandle" @size-change="sizeChangeHandle" v-bind="state.pagination" />
</div>
<!-- 导入excel -->
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="30%">
<c-form
:loading="loading"
ref="dataFormRef"
:model="addField"
:form-data="formData"
:form-field="addField"
:tools-config="{ noToolsShow: true }"
:rules="rules"
/>
<template #footer>
<div class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="onSub"> 确定 </el-button>
</div>
</template>
</el-dialog>
</div>
</template>
HTML部分主要是通过传入的formData参数遍历formItem内部的表单类型,目前内部有写了常用的input textArea switch select treeSelect等组件,并且有一个插槽可在配置的时候传入slotName去绑定关联,并且将当前配置的表单项所有的参数进行传参,方便特殊样式的需求,在formitem同级有个插槽,也可根据项目需求单独书写,目前不是太完善,未来会将这个插槽再进行更好的封装,目前只能用一次,某些项目可能不太够,对象的switch也封装了相对于的事件等,通过透传属性可无需对form固有属性进行单独传参,
import { defineProps, ref } from 'vue';
import { Hide } from '@element-plus/icons-vue';
const formRef = ref();
const passwordHide = ref(true);
const props: any = defineProps({
formField: { type: Object, default: () => {} },
formData: { type: Array, default: () => [] },
loading: { type: Boolean, default: false, required: false },
isColumns: { type: Boolean, default: false, required: false },
addClick: { type: Function },
toolsConfig: { type: Object, default: () => {}, required: false },
customClass: { type: String, default: '', required: false },
formWrapperClass: { type: String, default: '', required: false },
});
const { toolsConfig, formWrapperClass, customClass } = props;
defineExpose({
formRef,
});
js部分内容比较少
.c_form {
width: 100%;
margin-bottom: 16px;
.tools {
display: flex;
justify-content: space-between;
}
}
.modalFormItem {
width: 50%;
justify-content: flex-end;
align-items: center;
:deep(.el-form-item__content) {
width: 3.95rem;
flex: none;
.el-select,
.el-input-number,
.el-input {
width: 3.95rem;
height: 0.5625rem;
.el-input-number__decrease,
.el-input-number__increase {
height: 50%;
}
}
.avatar-uploader .avatar {
width: 178px;
height: 178px;
display: block;
}
.avatar-uploader .el-upload {
border: 1px dashed var(--el-border-color);
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
transition: var(--el-transition-duration-fast);
}
.avatar-uploader .el-upload:hover {
border-color: var(--el-color-primary);
}
.el-icon.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 1.175rem;
height: 1.175rem;
text-align: center;
}
}
}
css部分预封装了双栏表单样式可配置isColumns为true展示
使用示例
简单的使用示例
<c-form
:model="addField"
:form-data="formData"
:form-field="addField"
:tools-config="{ noToolsShow: true }"
/>
const formData = [
{ label: '姓名', type: 'input', prop: 'name' },
];
const addField = ref({name:""})