<template>
|
<div class="form-content">
|
<div class="title" v-if="title">
|
<SectionTitle v-if="title" :title="title"></SectionTitle>
|
</div>
|
<el-form
|
v-bind="$attrs"
|
:model="formValues"
|
ref="editForm"
|
:label-width="labelWidth"
|
:inline="inline"
|
:class="`form-cols-${inline ? showColumn : '0'}`"
|
size="small"
|
:rules="formRules"
|
>
|
<el-form-item v-if="$slots.top" v-bind="topInfo">
|
<div :style="{width: inputWidth}">
|
<slot name="top"></slot>
|
</div>
|
</el-form-item>
|
|
<el-form-item
|
v-for="(item, index) in showList"
|
:prop="item.name"
|
:key="index"
|
:label="formType === 'search' ? item.label : `${item.label}:`"
|
:class="{'textarea-item': item.type === 'textarea' || item.isLong}"
|
>
|
<CommInput
|
:info="item"
|
@updateValue="updateValue"
|
:inputWidth="item.type === 'textarea' ? textAreaWidth : inputWidth"
|
></CommInput>
|
</el-form-item>
|
|
<el-form-item v-if="$slots.default">
|
<slot></slot>
|
</el-form-item>
|
|
<el-form-item v-if="buttons.length > 0" class="form-right">
|
<div class="from-buttons">
|
<p
|
v-for="(button, index) in buttons"
|
:key="typeof button.id === 'undefined' ? index : button.id"
|
>
|
<Fold
|
v-if="button.type === 'fold'"
|
:isShowDetail="isShowAll"
|
@handleClick="$emit('buttonAction', index, button)"
|
></Fold>
|
<el-button
|
v-else
|
size="small"
|
@click="$emit('buttonAction', index, button)"
|
:type="typeof button.type === 'undefined' ? 'primary' : button.type"
|
>{{button.text}}</el-button>
|
</p>
|
</div>
|
</el-form-item>
|
</el-form>
|
</div>
|
</template>
|
<script>
|
// 表单项-目前用于搜索部分
|
import SectionTitle from './SectionTitle'
|
import CommInput from './base/CommInput'
|
import Fold from './Fold'
|
export default {
|
components: {
|
CommInput,
|
SectionTitle,
|
Fold
|
},
|
props: {
|
/**
|
* list 表单数组(type: input, textarea, select, time, date, rangeDate)
|
* @example
|
* [ { "type": "input", "label": "申请编号:", "value": "", "name": "serialNo" }]
|
*/
|
list: {
|
type: [Object, Array],
|
default: v => []
|
},
|
|
formValues: {
|
type: Object,
|
default: () => {}
|
},
|
|
formRules: {
|
type: Object,
|
default: () => {}
|
},
|
|
/**
|
* buttons 按钮列表
|
* @example
|
* [ {"text": '搜索' }, {"type": "fold", text: '展开'}]
|
*/
|
buttons: {
|
type: Array,
|
default: v => []
|
},
|
|
// 是否展示全部表单项(控制展开与收起)
|
isShowAll: {
|
type: Boolean,
|
default: true
|
},
|
|
// 对应isShowAll为false的时候最多展示列表的个数
|
shortNum: {
|
type: Number,
|
default: 2
|
},
|
|
topInfo: {
|
type: Object,
|
default: () => {}
|
},
|
|
inline: {
|
type: Boolean,
|
default: true
|
},
|
|
// 输入框或select的宽度
|
inputWidth: {
|
type: String,
|
default: '220px'
|
},
|
|
// labelWidth: {
|
// type: String,
|
// default: '8em'
|
// },
|
|
textAreaWidth: {
|
type: String,
|
default: '500px'
|
},
|
|
// 标题
|
title: {
|
type: String,
|
default: ''
|
},
|
|
// 默认日期格式
|
dateFormate: {
|
type: String,
|
default: 'YYYY/MM/DD'
|
},
|
|
// 默认错误提示信息
|
errorMsg: {
|
type: String,
|
default: '输入有误'
|
},
|
|
// 显示列数(固定列数,0为不设置固定值)
|
column: {
|
type: [String, Number],
|
default: 0
|
},
|
|
// form类型
|
// search:搜索条件类(屏幕适应缩放3-4个)
|
// edit:编辑类(屏幕适应缩放2-3个)
|
// info:编辑处理类(自动判断是否为readonly,屏幕适应缩放2-3个)
|
// text:文本展示类(不会有输入框,屏幕适应缩放2-3个)
|
formType: {
|
type: String,
|
default: 'edit'
|
}
|
},
|
mounted() {
|
window.addEventListener('resize', this.updateClientWidth)
|
this.updateClientWidth()
|
},
|
data() {
|
return {
|
clientWidth: 0
|
}
|
},
|
methods: {
|
updateClientWidth() {
|
const clientWidth = document.documentElement.clientWidth || 0
|
this.clientWidth = clientWidth
|
},
|
// 更新值
|
updateValue(val, item, parentName) {
|
const { list } = this
|
const { name } = item
|
const realName = parentName || name
|
const index = list.findIndex(
|
({ name: ItemName }) => ItemName === realName
|
)
|
if (index < 0) {
|
return false
|
}
|
|
if (parentName) {
|
const { children = [], ...other } = list[index]
|
const temList = children.reduce((pre, curr) => {
|
const { name: subName } = curr
|
if (subName === name) {
|
curr = { ...curr, value: val }
|
}
|
pre.push({ ...curr })
|
return pre
|
}, [])
|
|
this.$emit('updateValue', index, { ...other, children: temList })
|
} else {
|
this.$emit('updateValue', index, {
|
...list[index],
|
value: val
|
})
|
}
|
},
|
|
// 统一输出数据格式,如日期格式化
|
formatInput(val) {
|
const { dateFormate } = this
|
if (Array.isArray(val)) {
|
return val.reduce((pre, curr) => {
|
pre.push(this.formatInput(curr))
|
return pre
|
}, [])
|
}
|
return val instanceof Date ? this.dayjs(val).format(dateFormate) : val
|
},
|
|
// 表单校验,未通过校验返回false,通过返回数据
|
validate() {
|
const { formValues } = this
|
let info = false
|
this.$refs.editForm.validate(valid => {
|
if (valid) {
|
info = formValues
|
}
|
})
|
return info
|
}
|
|
// getRule(item) {
|
// const { errorMsg } = this
|
// let { rules = [], name, value, children, validator, trigger = 'blur' } = item
|
// let result = []
|
// if (typeof validator === 'function') {
|
// result.push({ validator, trigger })
|
// } else {
|
// if (Array.isArray(children)) {
|
// if (children.length > 0) {
|
// // rules = [...rules, this.getRule()]
|
// const childRule = children.reduce((childPre, childCurr) => {}, [])
|
// if (childRule.length > 0) {
|
// rules = [...rules, ...childRule]
|
// }
|
// }
|
// } else {
|
// if (rules.length > 0) {
|
// result = children.reduce((childPre, childCurr) => {
|
// if (childCurr === 'required') {
|
// childPre.push({
|
// validator: () => value, // array
|
// trigger
|
// })
|
// }
|
// return childPre
|
// }, result)
|
// }
|
// }
|
// }
|
// // return [
|
// // {validator: 'fn', trigger: 'blur'}
|
// // ]
|
// }
|
|
// 获取表单输出结果,不校验
|
// getValues() {
|
// const { ruleForm } = this
|
// return ruleForm
|
// },
|
|
// 重置
|
// reset() {
|
// // 该方法可能会废弃
|
// const { list } = this
|
// list.forEach((item, index) => {
|
// let { children, attrs } = item
|
// // 只读对象不重置
|
// if (Array.isArray(attrs) && attrs.length > 0) {
|
// if (
|
// attrs.some(
|
// item =>
|
// (typeof item === 'string' &&
|
// (item === 'readonly' || item === 'disabled')) ||
|
// (typeof item === 'object' &&
|
// (item['readonly'] || item['disabled']))
|
// )
|
// ) {
|
// return false
|
// }
|
// }
|
// if (Array.isArray(children)) {
|
// this.$emit('updateValue', index, {
|
// ...item,
|
// children: children.reduce((pre, curr) => {
|
// pre.push({
|
// ...curr,
|
// value: this.getResetValue(curr, item)
|
// })
|
// return pre
|
// }, [])
|
// })
|
// } else {
|
// this.$emit('updateValue', index, {
|
// ...item,
|
// value: this.getResetValue(item)
|
// })
|
// }
|
// })
|
// },
|
|
// 获取重置值
|
// getResetValue(item, parent) {
|
// // 该方法可能会废弃
|
// let { options, valueKey, value } = item
|
// let key = valueKey || 'value'
|
// if (parent) {
|
// const { valueKey: parentValueKey, value: parentValue } = parent
|
// valueKey = parentValueKey || valueKey
|
// value = parentValue || valueKey
|
// }
|
// let result = Array.isArray(value) ? [] : ''
|
// if (Array.isArray(options) && options[0]) {
|
// const tempVal = options[0][key] || ''
|
// result = Array.isArray(value) ? [tempVal] : tempVal
|
// }
|
// return result
|
// }
|
},
|
computed: {
|
showColumn() {
|
const { formType, column, clientWidth } = this
|
if (Number(column) !== 0) {
|
return Number(column)
|
}
|
const num = formType === 'search' ? 4 : 3
|
if (clientWidth > 1460) {
|
return num
|
}
|
return num - 1
|
},
|
labelWidth() {
|
const { formType } = this
|
return formType === 'search' ? '84px' : '160px'
|
},
|
showList() {
|
const { list, isShowAll, showColumn } = this
|
let result = [...list]
|
if (!isShowAll) {
|
result = result.slice(0, showColumn === 4 ? showColumn - 1 : showColumn)
|
}
|
return result
|
},
|
// 表单校验规则
|
rules() {
|
const { list } = this
|
return list.reduce((pre, curr) => {
|
// const rule = this.getRule(curr)
|
// if (rule.length > 0) {
|
// pre[curr.name] = rule
|
// }
|
// let { rules = [], name, children } = curr
|
// if (Array.isArray(children)) {
|
// if(children.length > 0){
|
// pre[name] = this.getRule(children)
|
// }
|
// } else {
|
// if (rules.length > 0) {
|
// pre[name] = rules.reduce((rulePre, ruleItem) => {
|
// if (typeof ruleItem === 'string') {
|
// // required
|
// rulePre.push({
|
// validator: ()=>
|
// })
|
// }
|
// }, [])
|
// }
|
// }
|
|
// if (Array.isArray(rules)) {
|
// const rulesObj = rules.reduce((rulePre, ruleItem) => {
|
// if (typeof ruleItem === 'string') {
|
// ruleItem = { [ruleItem]: true }
|
// }
|
// rulePre.push({ message: errorMsg, ...ruleItem })
|
// return rulePre
|
// }, [])
|
|
// if (Array.isArray(children)) {
|
// name = children.forEach(({ name: subName }) => {
|
// pre[subName] = [...rulesObj]
|
// })
|
// } else {
|
// pre[name] = [...rulesObj]
|
// }
|
// }
|
return pre
|
}, {})
|
}
|
// 表单输出
|
// ruleForm() {
|
// const { list } = this
|
// return list.reduce((pre, curr) => {
|
// const { name, names, value, children } = curr
|
// // 父级不包含value,则取子级
|
// if (typeof value === 'undefined' && Array.isArray(children)) {
|
// children.forEach(subItem => {
|
// const { name: subName, value: subValue } = subItem
|
// pre[subName] = this.formatInput(subValue)
|
// })
|
// } else if (Array.isArray(names) && Array.isArray(value)) {
|
// // 将数组值传送到names字段对应的key中
|
// names.forEach((subName, index) => {
|
// pre[subName] = this.formatInput(value[index] || '')
|
// })
|
// } else {
|
// pre[name] = this.formatInput(value)
|
// }
|
// return pre
|
// }, {})
|
// }
|
}
|
}
|
</script>
|
<style lang="postcss" scoped>
|
.form-content {
|
& >>> .el-form {
|
display: grid;
|
& .el-form-item {
|
display: flex;
|
align-items: center;
|
padding-right: 40px;
|
margin: 0 0 24px 0;
|
& label {
|
padding: 0;
|
text-align: right;
|
margin-right: 10px;
|
line-height: 16px;
|
}
|
& .el-form-item__content {
|
flex: 1;
|
margin: 0;
|
}
|
&.right-item {
|
justify-content: right;
|
grid-column-start: 3;
|
grid-column-end: 4;
|
}
|
& .el-date-editor {
|
width: 100%;
|
}
|
& .el-input--small {
|
font-size: 14px;
|
}
|
& .el-select {
|
width: 100%;
|
}
|
}
|
& .form-sign {
|
& label::after {
|
content: ':';
|
}
|
}
|
}
|
|
& >>> .el-tag--info {
|
max-width: 94%;
|
overflow: hidden;
|
}
|
& >>> .el-select__tags-text {
|
display: inline-block;
|
max-width: 110px;
|
overflow: hidden;
|
white-space: nowrap;
|
text-overflow: ellipsis;
|
}
|
& .from-buttons {
|
/* padding-left: 82px; */
|
display: flex;
|
justify-content: flex-end;
|
& p {
|
margin: 0;
|
padding: 0;
|
}
|
& >>> .el-button {
|
height: 32px;
|
font-size: 12px;
|
margin-left: 12px;
|
}
|
& .normal-button {
|
height: 32px;
|
font-size: 14px;
|
margin-left: 22px;
|
}
|
}
|
& >>> .el-tag__close {
|
top: -5px;
|
right: -6px;
|
}
|
& >>> .el-form-item__label {
|
color: #888888;
|
}
|
& >>> .el-input__inner {
|
border-color: #eeeeee;
|
color: #222222;
|
}
|
& .long-lable >>> .el-form-item__label {
|
line-height: 1.3em;
|
padding-top: 0;
|
}
|
& .textarea {
|
width: 100%;
|
& >>> textarea {
|
height: 100%;
|
}
|
}
|
& .range-separato {
|
width: 10px;
|
display: inline-block;
|
text-align: center;
|
}
|
& .range-input-item {
|
display: inline-block;
|
}
|
|
& .form-cols-1 {
|
grid-template-columns: 1fr;
|
& .textarea-item {
|
grid-column-start: 1;
|
grid-column-end: 1;
|
}
|
& .form-right {
|
grid-column-start: 1;
|
grid-column-end: 1;
|
}
|
}
|
|
& .form-cols-2 {
|
grid-template-columns: repeat(2, 1fr);
|
& .textarea-item {
|
grid-column-start: 1;
|
grid-column-end: 3;
|
}
|
& .form-right {
|
grid-column-start: 2;
|
grid-column-end: 3;
|
}
|
}
|
& .form-cols-3 {
|
grid-template-columns: repeat(3, 1fr);
|
& .textarea-item {
|
grid-column-start: 1;
|
grid-column-end: 4;
|
}
|
& .form-right {
|
grid-column-start: 3;
|
grid-column-end: 4;
|
}
|
}
|
& .form-cols-4 {
|
grid-template-columns: repeat(4, 1fr);
|
& .textarea-item {
|
grid-column-start: 1;
|
grid-column-end: 5;
|
}
|
& .form-right {
|
grid-column-start: 4;
|
grid-column-end: 5;
|
}
|
}
|
}
|
</style>
|