Vue2-封装一个看起来像左右分布表格的表单组件
效果
1. 无编辑权限:显示普通表格
2. 有编辑权限:根据配置显示编辑控件
核心代码
<el-form:ref="formRef":model="data":label-width="labelWidth"label-position="left"target="stop":rules="rules"><el-rowv-for="(row, rowIndex) in items":key="rowIndex":gutter="0":class="`form-row-${rowIndex}`"><el-colv-for="(item, index) in isArray(row)":key="index":span="item.span || 24 / row.length":class="item.colClassName || null"style="padding: 0"><el-form-item:key="item.label || index":style="item.styles":class="[isRequire(item) ? 'form-item-required' : 'form-item-notRequired',!item.label ? 'hidden-form-item-label' : '',item.className,item.attrs && item.attrs.disabled ? 'hidden-tips' : '',]":label="item.label":prop="item.prop":rules="item.rules":label-width="item.labelWidth || '120px'":name="item.prop"><!-- 只读模式显示字段值 --><div v-if="!hasEditPermission" class="readonly-value"><slotv-if="item.textSlot":row="data":name="item.textSlotName"/><span v-else>{{ data[item.prop] }}</span></div><template v-else><!--自定义插槽--><slotv-if="item.type == $const.DialogCompType.slot":item="item":name="item.slotName"/><!--单行输入框--><el-inputv-if="item.type == $const.DialogCompType.input"v-model="data[item.prop]":name="item.prop"auto-complete="on"class="item-inputs":style="{ width: `${item.width}` }":placeholder="placeholderFormate(item)"v-bind="item.attrs"v-on="item.listeners"><template v-if="item.slot" :slot="item.slotName">{{item.slotContent}}</template></el-input><!--远程搜索选择器--><remote-search-selectorv-if="item.type == $const.DialogCompType.remoteSearchSelector":init-value="data[item.prop]"class="item-inputs":placeholder="placeholderFormate(item)":newComp="true"v-bind="item.attrs":options="item.optionList":show-value="item.showValue":remote-methods="item.remoteMethod":style="{ width: `${item.width}`}"v-on="item.listeners"@valueChange="remoteSearchValueChage($event, data, item)"/><!--数字输入--><el-input-numberv-if="item.type == $const.DialogCompType.number"v-model="data[item.prop]"class="item-inputs":style="{ width: `${item.width}` }":placeholder="placeholderFormate(item)"v-bind="item.attrs"v-on="item.listeners"/><!--多行输入--><el-inputv-if="item.type == $const.DialogCompType.textarea"v-model="data[item.prop]":name="item.prop"auto-complete="on"class="item-inputs":style="{ width: `${item.width}` }"type="textarea":placeholder="placeholderFormate(item)"v-bind="item.attrs":autosize="item.attrs && item.attrs.autosize ? item.attrs.autosize : true"v-on="item.listeners"/><!--日期选择器--><el-date-pickerv-if="item.type == $const.DialogCompType.datePicker"v-model="data[item.prop]"class="item-inputs":type="(item.attrs && item.attrs.type) || 'date'":placeholder="placeholderFormate(item)":style="{ width: `${item.width}` }"v-bind="item.attrs"v-on="item.listeners"/><!--日期时间选择器--><el-date-pickerv-if="item.type == $const.DialogCompType.dateTime"v-model="data[item.prop]"class="item-inputs"type="datetime":placeholder="placeholderFormate(item)":style="{ width: `${item.width}` }"v-bind="item.attrs"v-on="item.listeners"/><!--日期时间选择器-带标记封装组件--><date-picker-wrapv-if="item.type == $const.DialogCompType.datePickerColor":date="data[item.prop]"class="item-inputs":placeholder="placeholderFormate(item)":style="{ width: `${item.width}` }"v-bind="item.attrs"v-on="item.listeners"/><!--时间范围选择--><el-date-pickerv-if="item.type == $const.FormCompType.daterange"v-model="data[item.prop]":type="(item.attrs && item.attrs.type) || 'daterange'":placeholder="placeholderFormate(item)":style="{ width: `${item.width || width || '100%'}` }":picker-options="{ disabledDate:daterangeDisabledDate }"v-bind="item.attrs"v-on="item.listeners"@change="eventHandler($event, {name: 'change',events: item.listeners,item,})"/><!-- 日期和时间范围选择 --><el-date-pickerv-if="item.type == $const.FormCompType.datetimerange"v-model="data[item.prop]"type="datetimerange":placeholder="placeholderFormate(item)":style="{ width: `${item.width || width || '100%'}` }"v-bind="item.attrs"v-on="item.listeners"@change="eventHandler($event, {name: 'change',events: item.listeners,item,})"/><!--开关--><el-switchv-if="item.type == $const.DialogCompType.switch"v-model="data[item.prop]"v-bind="item.attrs"v-on="item.listeners"/><!--下拉菜单--><el-dropdownv-if="item.type == $const.DialogCompType.dropdown"v-bind="item.attrs"v-on="item.listeners"><el-button v-bind="item.dropdownButtonsAttrs">{{ item.dropdownLabel }}<i class="el-icon-arrow-down el-icon--right" /></el-button><el-dropdown-menu slot="dropdown"><el-dropdown-itemv-for="dItem in item.dropdownItem":key="dItem.label"v-bind="dItem.attrs"v-on="dItem.listeners">{{ dItem.label }}</el-dropdown-item></el-dropdown-menu></el-dropdown><!--普通下拉选择器--><SelectorWrapv-if="item.type == $const.DialogCompType.select":key="item.prop":item="item":data="data"v-bind="item.attrs"v-on="item.listeners"/><!--单选框--><el-radio-groupv-if="item.type == $const.DialogCompType.radio"v-model="data[item.prop]"class="item-inputs":style="{ width: `${item.width}` }"v-bind="item.attrs"v-on="item.listeners"><el-radiov-for="option in item.optionList":key="option.id || option.value":label="option.value">{{ option.label }}</el-radio></el-radio-group><!--滑动条--><el-sliderv-if="item.type == $const.DialogCompType.slider"v-model="data[item.prop]"class="item-inputs"v-bind="item.attrs"v-on="item.listeners"/><!--警告--><el-alertv-if="item.type == $const.DialogCompType.alert"v-bind="item.attrs"/><el-dividerv-if="item.type == $const.DialogCompType.divider"v-bind="item.attrs"><span v-if="item.tips">{{ item.tips }}</span></el-divider><!--文件上传--><file-uploadv-if="item.type == $const.DialogCompType.files"class="item-inputs"v-bind="item.attrs"v-on="item.listeners"/><!--按钮组--><divv-if="item.type == $const.DialogCompType.buttons"class="dialog-buttons":style="{display: 'flex','justify-content': buttonsAlign[item.align] || 'flex-end',}"><el-buttonv-for="but in item.buttons":key="but.label":type="but.type"v-bind="but.attrs"size="small"@click="submitValidate(but.validate, but.reset, but.event)">{{ but.label }}</el-button></div><!--富文本编辑器--><tinymcev-if="item.type == $const.DialogCompType.editor"v-model="data[item.prop]":height="item.height"/></template></el-form-item></el-col></el-row></el-form>