|
|
|
<template>
|
|
|
|
<ElForm :style="getStyle()" :label-width="labelWidth" class="FormConfig" size="mini">
|
|
|
|
<ElFormItem class="formItem" :rules="getRules(item)" v-for="(item, index) in formList" :key="item.key"
|
|
|
|
:label="item.label" :style="gridStyle(item, index)">
|
|
|
|
<slot :name="item.key" :data="item" :formData="formData">
|
|
|
|
<component :is="getComponent(item.type)" v-bind="getBindData(item)" v-model="formData[item.key]" />
|
|
|
|
</slot>
|
|
|
|
</ElFormItem>
|
|
|
|
</ElForm>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script>
|
|
|
|
const files = require.context('./components', true, /^.\/[^/]+\/index\.vue$|^.\/[^/]+.vue$/);
|
|
|
|
|
|
|
|
const components = files.keys().reduce((prev, key) => {
|
|
|
|
prev[key.match(/[^./]+/g)[0]] = files(key).default;
|
|
|
|
|
|
|
|
return prev;
|
|
|
|
}, {})
|
|
|
|
|
|
|
|
export default {
|
|
|
|
name: 'FormConfig',
|
|
|
|
components: {
|
|
|
|
// FormInput,
|
|
|
|
// FormTimePicker
|
|
|
|
},
|
|
|
|
provide() {
|
|
|
|
return {
|
|
|
|
getComponent: this.getComponent,
|
|
|
|
getBindData: this.getBindData
|
|
|
|
}
|
|
|
|
},
|
|
|
|
props: {
|
|
|
|
/**
|
|
|
|
* {
|
|
|
|
* label: String;
|
|
|
|
* key: String;
|
|
|
|
* type: 'input' | 'timePicker',
|
|
|
|
* gridArea?: "",
|
|
|
|
* gridColumn?: "",
|
|
|
|
* gridRow?: "",
|
|
|
|
* options?: {}
|
|
|
|
* }[]
|
|
|
|
*/
|
|
|
|
formList: {
|
|
|
|
type: Array,
|
|
|
|
default: () => []
|
|
|
|
},
|
|
|
|
labelWidth: {
|
|
|
|
type: String,
|
|
|
|
default: "auto"
|
|
|
|
},
|
|
|
|
rules: {
|
|
|
|
type: Object,
|
|
|
|
default: null
|
|
|
|
},
|
|
|
|
column: {
|
|
|
|
type: [String, Number],
|
|
|
|
default: "3"
|
|
|
|
}
|
|
|
|
},
|
|
|
|
data() {
|
|
|
|
return {
|
|
|
|
formData: {}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
created() {
|
|
|
|
this.formData = this.formList.reduce((prev, { key, default: defaultData }) => {
|
|
|
|
prev[key] = defaultData || null;
|
|
|
|
|
|
|
|
return prev
|
|
|
|
}, {})
|
|
|
|
},
|
|
|
|
computed: {
|
|
|
|
gridStyle() {
|
|
|
|
return (item, index) => ({
|
|
|
|
gridRow: `span ${item.gridRow || 1}`,
|
|
|
|
gridColumn: `span ${item.gridColumn || item.isAlone && this.column || 1}`,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
},
|
|
|
|
methods: {
|
|
|
|
getStyle() {
|
|
|
|
return {
|
|
|
|
gridTemplateColumns: `repeat(${this.column}, 1fr)`,
|
|
|
|
}
|
|
|
|
},
|
|
|
|
getBindData(item) {
|
|
|
|
return {
|
|
|
|
placeholder: "请输入",
|
|
|
|
...item.options
|
|
|
|
}
|
|
|
|
},
|
|
|
|
getComponent(type) {
|
|
|
|
if (!type) type = 'input';
|
|
|
|
|
|
|
|
const componentKey = type.replace(/^[a-z]/, word => word.toUpperCase());
|
|
|
|
|
|
|
|
const ElComponentKey = `El${componentKey}`;
|
|
|
|
|
|
|
|
return components[componentKey] || components[ElComponentKey] || ElComponentKey;
|
|
|
|
},
|
|
|
|
getRules(item) {
|
|
|
|
if (this.rules?.[item.key]) return this.rules[item.key];
|
|
|
|
|
|
|
|
if (item.rules) return item.rules;
|
|
|
|
|
|
|
|
if (item.required) return [
|
|
|
|
{
|
|
|
|
required: true,
|
|
|
|
message: `${item.options?.placeholder || `${item.label}不能为空`}`,
|
|
|
|
trigger: "blur",
|
|
|
|
},
|
|
|
|
]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<style lang='scss' scoped>
|
|
|
|
.FormConfig {
|
|
|
|
display: grid;
|
|
|
|
align-content: start;
|
|
|
|
width: 100%;
|
|
|
|
gap: 15px 15px;
|
|
|
|
overflow-x: hidden;
|
|
|
|
|
|
|
|
.formItem {
|
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
::v-deep {
|
|
|
|
.el-form-item {
|
|
|
|
align-items: center;
|
|
|
|
margin: 0;
|
|
|
|
height: 100%;
|
|
|
|
|
|
|
|
&:first-child {
|
|
|
|
.el-form-item__label-wrap {
|
|
|
|
// padding-top: 9px;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.el-form-item__label-wrap {
|
|
|
|
width: fit-content;
|
|
|
|
}
|
|
|
|
|
|
|
|
.el-form-item__label {
|
|
|
|
height: 22px;
|
|
|
|
font-size: 15px;
|
|
|
|
// font-family: PingFang SC, PingFang SC;
|
|
|
|
font-weight: 400;
|
|
|
|
color: #3DE8FF;
|
|
|
|
line-height: 19px;
|
|
|
|
// -webkit-background-clip: text;
|
|
|
|
// -webkit-text-fill-color: transparent;
|
|
|
|
}
|
|
|
|
|
|
|
|
.el-form-item__content {
|
|
|
|
margin: 0 !important;
|
|
|
|
flex: 1;
|
|
|
|
height: 100%;
|
|
|
|
|
|
|
|
.el-input__prefix {
|
|
|
|
color: #fff;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
</style>
|