Created
July 1, 2019 02:54
-
-
Save wisetc/9ce627ce55073969c40d5f446b09e070 to your computer and use it in GitHub Desktop.
Field definition
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.trusteeship-form { | |
$labelWidth: 8em; | |
display: flex; | |
flex-wrap: wrap; | |
.suffix-text { | |
color: #666; | |
position: relative; | |
left: -2em; | |
} | |
.el-input { | |
width: 18em; | |
} | |
.el-form-item__label { | |
width: $labelWidth; | |
text-align: right; | |
} | |
._form-item { | |
width: 48%; | |
padding-right: 1.2em; | |
} | |
._hr { | |
width: 100%; | |
margin-bottom: 24px; | |
margin-top: -8px; | |
border-color: #E0E0E0; | |
border-width: 1px; | |
border-top: none; | |
} | |
.nested-field-set { | |
display: flex; | |
width: 50%; | |
.el-form-item__content > div { | |
width: 3em; | |
.el-input { | |
width: 100%; | |
} | |
} | |
.el-select .el-input .el-input__icon { | |
display: none; | |
} | |
.el-select .el-input__icon+.el-input__inner { | |
padding-right: 5px; | |
padding-left: 5px; | |
text-align: center; | |
} | |
.el-form-item { | |
display: flex; | |
.el-form-item__label { | |
width: 3em; | |
} | |
} | |
// 合成的字段 | |
.nest-field-set__label { | |
width: $labelWidth; | |
padding-top: 11px; | |
padding-right: 12px; | |
line-height: 1; | |
text-align: right; | |
font-size: 14px; | |
color: #48576a; | |
} | |
} | |
.linebreak { | |
display: block; | |
width: 100%; | |
} | |
.full-width-form-item { | |
width: 80%; | |
.el-form-item__content { | |
width: 80%; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<el-form ref="form" inline class="trusteeship-form" :model="form" @change.native="handleFormChange"> | |
<template v-for="(field, i) in fieldDefs"> | |
<template v-if="show(field)"> | |
<!-- 嵌套类型,手动嵌套一波 --> | |
<div :key="i" v-if="field.widget === 'div'" v-bind="field.rest" class="nested-field-set"> | |
<div class="nest-field-set__label">{{field.label}}</div> | |
<template v-for="(nestedField, fieldK) in field.fieldSet"> | |
<el-form-item | |
v-if="show(nestedField)" | |
:key="fieldK" | |
:prop="nestedField.id" | |
:label="nestedField.hideLabel ? '' : nestedField.label" | |
:rules="nestedField.rules" | |
:error="errors[field.id]" | |
> | |
<el-input | |
v-if="!nestedField.widget" | |
:value="form[nestedField.id]" | |
@input="v => { form[nestedField.id] = isNumber(nestedField.type) ? Number(v) : v }" | |
placeholder="" | |
v-bind="nestedField.rest" | |
> | |
<!-- <template v-if="nestedField.suffixText" slot="append">{{nestedField.suffixText}}</template> --> | |
</el-input> | |
<el-select | |
v-else-if="nestedField.widget === 'select'" | |
v-model="form[nestedField.id]" | |
placeholder="" | |
v-bind="nestedField.rest" | |
> | |
<el-option v-for="(opt, j) in nestedField.options" :key="j" v-bind="opt"></el-option> | |
</el-select> | |
<span class="suffix-text" v-if="nestedField.suffixText">{{nestedField.suffixText}}</span> | |
</el-form-item> | |
</template> | |
</div> | |
<template v-else-if="field.widget === 'textarea'"> | |
<div :key="'key' + i" class="linebreak"></div> | |
<el-form-item | |
:key="i" | |
:prop="field.id" | |
:label="field.label" | |
:rules="field.rules" | |
class="full-width-form-item" | |
> | |
<el-input | |
v-model="form[field.id]" | |
type="textarea" | |
v-bind="field.rest" | |
/> | |
</el-form-item> | |
</template> | |
<el-form-item | |
v-else | |
:key="i" | |
:prop="field.id" | |
:label="field.hideLabel ? '' : field.label" | |
:rules="field.rules" | |
:error="errors[field.id]" | |
class="_form-item" | |
> | |
<el-input | |
v-if="!field.widget" | |
:value="form[field.id]" | |
@input="v => { form[field.id] = isNumber(field.type) ? Number(v) : v }" | |
v-model="form[field.id]" | |
placeholder="" | |
v-bind="field.rest" | |
> | |
<template v-if="field.suffixText" slot="append">{{field.suffixText}}</template> | |
</el-input> | |
<el-select v-else-if="field.widget === 'select'" v-model="form[field.id]"> | |
<el-option v-for="(opt, j) in field.options" :key="j" v-bind="opt"></el-option> | |
</el-select> | |
<el-cascader | |
v-else-if="field.widget === 'cascader'" | |
v-model="form[field.id]" | |
:options="field.options" | |
v-bind="field.rest" | |
> | |
</el-cascader> | |
<el-radio-group v-else-if="field.widget === 'radio'" v-model="form[field.id]"> | |
<el-radio :label="true">是</el-radio> | |
<el-radio :label="false">否</el-radio> | |
</el-radio-group> | |
<el-radio-group v-else-if="field.widget === 'radioGroup' && Array.isArray(field.options)" v-model="form[field.id]"> | |
<el-radio v-for="(o, i) in field.options" :key="i" :label="o.value">{{o.label}}</el-radio> | |
</el-radio-group> | |
<el-date-picker | |
v-else-if="field.widget === 'date'" | |
v-model="form[field.id]" | |
v-bind="field.rest" | |
> | |
</el-date-picker> | |
</el-form-item> | |
</template> | |
<hr :key="'key' + i" v-if="field.close" class="_hr" /> | |
</template> | |
</el-form> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { dateStr, getCascaderLabel, getLabel, cycle2Number, isDate, getTime } from '../utils' | |
export default { | |
methods: { | |
getFieldObject(fieldDef, form) { | |
const id = fieldDef.id | |
let value = form[id] | |
let labelValue | |
if (typeof fieldDef.postMethod === 'function') { | |
value = fieldDef.postMethod(value) | |
} | |
if (typeof fieldDef.formatter === 'function' && value) { | |
labelValue = fieldDef.formatter(value) | |
} else if (isDate(fieldDef.type) && value) { | |
// date | |
value = getTime(value) | |
labelValue = dateStr(value) | |
} else if (fieldDef.type === Array && fieldDef.widget === 'date') { | |
// date array | |
if (Array.isArray(value) && value.filter(Boolean).length) { | |
labelValue = value.map(t => dateStr(t)).join(' 至 ') | |
} else { | |
value = null | |
labelValue = 'N/A' | |
} | |
} else if (fieldDef.widget === 'cascader') { | |
labelValue = getCascaderLabel(value, fieldDef.options) | |
} else if (fieldDef.options && Array.isArray(fieldDef.options)) { | |
labelValue = getLabel(value, fieldDef.options) | |
} | |
return { | |
label: fieldDef.label, | |
id, | |
value, | |
labelValue, | |
hidden: fieldDef.hidden, | |
} | |
} | |
}, | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
enum Widget { | |
div, | |
radio, | |
radioGroup, | |
select, | |
date | |
} | |
interface Option { | |
label: string; | |
value: string; | |
} | |
interface Field { | |
label: string; | |
hideLabel?: boolean; | |
id: string; | |
type: Function; | |
defaultValue?: any; | |
belongsTo?: string; | |
widget?: Widget; | |
options?: Option[]; | |
fetchMethod?: () => Promise<any>; | |
delayFetchMethod?: () => Promise<any>; | |
suffixText?: String; | |
postMethod?(val: any): any; | |
fieldSet?: Field[]; | |
close?: boolean; | |
rest?: object; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment