<template>
|
<div class="comm-input" :class="{ 'range-split': isShowRange }">
|
<div
|
v-if="Array.isArray(info.children)"
|
class="range-input el-range-editor el-input__inner"
|
>
|
<CommInput
|
v-for="(subItem, subIndex) in info.children"
|
:info="{
|
attrs: info.attrs || [],
|
rules: info.rules || [],
|
type: info.type,
|
...subItem,
|
}"
|
@updateValue="updateValue"
|
:parentName="info.name"
|
:key="subIndex"
|
:inputWidth="`${parseInt(inputWidth) / info.children.length - 6}px`"
|
:isShowRange="subIndex > 0 && subIndex < info.children.length"
|
></CommInput>
|
</div>
|
<component
|
v-else-if="info.type === 'select'"
|
@input="updateValue($event, info, parentName)"
|
:name="info.name"
|
:value="info.value"
|
v-bind="attrInfo"
|
v-bind:is="componentNames[info.type]"
|
>
|
<el-option
|
v-for="(optionsItem, optionsIndex) in info.options"
|
:key="optionsIndex"
|
:label="optionsItem.label"
|
:value="optionsItem.value"
|
></el-option>
|
</component>
|
|
<component
|
v-else-if="info.type === 'filterSelect'"
|
@input="updateValue($event, info, parentName)"
|
:name="info.name"
|
:value="info.value"
|
v-bind="attrInfo"
|
:filter-method="dataFilter"
|
v-bind:is="'el-select'"
|
>
|
<el-option
|
v-for="(optionsItem, optionsIndex) in info.options"
|
:key="optionsIndex"
|
:label="optionsItem.label"
|
:value="optionsItem.value"
|
></el-option>
|
</component>
|
|
<div
|
v-else-if="info.type === 'customer'"
|
@click="updateValue($event, info, parentName)"
|
class="form-customer"
|
>
|
<p>{{ info.value }}</p>
|
<i class="el-icon-tickets"></i>
|
</div>
|
|
<p
|
v-else-if="!componentNames[info.type] || info.type === 'text'"
|
class="form-text"
|
>
|
{{ info.value | fRecord(info) }}
|
</p>
|
|
<component
|
v-else
|
@input="updateValue($event, info, parentName)"
|
:name="info.name"
|
:value="info.value"
|
v-bind="attrInfo"
|
v-bind:is="componentNames[info.type]"
|
></component>
|
</div>
|
</template>
|
<script>
|
// type input textarea inputs select
|
export default {
|
name: 'CommInput',
|
props: {
|
/**
|
* info 单条配置信息 @example
|
* {type: 'input', label: '报单人:', value: '',name: 'formbllevel',attrs: [],rules:[]}
|
* */
|
info: {
|
type: Object,
|
required: true,
|
},
|
|
// 自身递归时用到,外部不用传入
|
parentName: {
|
type: String,
|
default: '',
|
},
|
|
// 不同类型默认配置配置
|
typeInfo: {
|
type: Object,
|
default: () => {},
|
},
|
|
// 输入框或select的宽度
|
inputWidth: {
|
type: String,
|
default: '220px',
|
},
|
|
isShowRange: {
|
type: Boolean,
|
default: false,
|
},
|
},
|
|
data() {
|
return {
|
defaultTypeInfo: {
|
input: {
|
placeholder: '请输入',
|
maxLength: 300,
|
},
|
textarea: {
|
placeholder: '请输入',
|
maxLength: 3000,
|
},
|
select: {
|
placeholder: '请选择',
|
},
|
time: {
|
placeholder: '请选择',
|
},
|
date: {
|
placeholder: '请选择',
|
},
|
dateRange: {
|
placeholder: '请选择',
|
},
|
},
|
componentNames: {
|
input: 'el-input',
|
textarea: 'el-input',
|
select: 'el-select',
|
time: 'el-time-select',
|
timePicker: 'el-time-picker',
|
timeRange: 'el-time-picker',
|
date: 'el-date-picker',
|
dateRange: 'el-date-picker',
|
},
|
}
|
},
|
|
methods: {
|
// 更新值
|
updateValue(val, item, parentName) {
|
this.$emit('updateValue', val, item, parentName)
|
},
|
dataFilter(val, filter = true) {
|
const { info } = this
|
this.$emit('updateValue', val, info, '', filter)
|
},
|
},
|
computed: {
|
// 导出属性信息
|
attrInfo() {
|
let { info, mixTypeInfo } = this
|
const { attrs, rules, type } = info
|
let result = mixTypeInfo[type] ? { ...mixTypeInfo[type] } : {}
|
|
// rules中如果设置了maxLength,则转移到属性中
|
if (Array.isArray(rules) && rules.length > 0) {
|
const maxItem = rules.find((item) =>
|
Object.keys(item).includes('maxLength')
|
)
|
if (maxItem) {
|
result.maxLength = maxItem['maxLength']
|
}
|
}
|
if (type === 'textarea') {
|
result.type = 'textarea'
|
}
|
if (type === 'dateRange') {
|
result.type = 'daterange'
|
result.startPlaceholder = '开始日期'
|
result.endPlaceholder = '结束日期'
|
}
|
if (type === 'timeRange') {
|
result.isRange = true
|
result.startPlaceholder = '开始时间'
|
result.endPlaceholder = '结束时间'
|
}
|
|
if (Array.isArray(attrs) && attrs.length > 0) {
|
result = attrs.reduce(
|
(pre, curr) => {
|
if (typeof curr === 'string') {
|
curr = { [curr]: true }
|
}
|
if (typeof curr === 'object') {
|
pre = { ...pre, ...curr }
|
// 只读或disabled元素不需要默认placeholder
|
if (curr.disabled || curr.readonly) {
|
pre.placeholder = ''
|
}
|
}
|
return { ...pre }
|
},
|
{ ...result }
|
)
|
}
|
return result
|
},
|
|
// 合并配置项
|
mixTypeInfo() {
|
const { typeInfo, defaultTypeInfo } = this
|
return { ...defaultTypeInfo, ...typeInfo }
|
},
|
},
|
}
|
</script>
|
<style lang="postcss" scoped>
|
.comm-input {
|
& .range-input {
|
padding: 0;
|
line-height: 32px;
|
height: 32px;
|
& .comm-input {
|
line-height: 24px;
|
}
|
& >>> input {
|
line-height: 24px;
|
height: 24px;
|
border: none;
|
}
|
}
|
& .form-text {
|
margin: 0;
|
line-height: 16px;
|
}
|
& >>> input[readonly] {
|
color: #888888;
|
}
|
& .form-customer {
|
background: #f5f7fa;
|
border: 1px solid #f5f7fa;
|
border-radius: 4px;
|
cursor: pointer;
|
display: flex;
|
align-items: center;
|
color: #888888;
|
padding: 0 15px;
|
& p {
|
margin: 0;
|
padding: 0;
|
flex: 1;
|
height: 32px;
|
overflow: hidden;
|
}
|
}
|
}
|
.range-split {
|
position: relative;
|
&::before {
|
content: '-';
|
position: absolute;
|
z-index: 1;
|
line-height: 24px;
|
left: -4px;
|
top: 0;
|
}
|
}
|
</style>
|