form-render.vue
3.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
<template>
<!-- 在row上使用flex,防止表单组件大小不一导致错位 -->
<el-row type="flex" style="flex-wrap: wrap;width: 100%;" :class="contentClass || 'eagle-form__group-content'">
<template v-for="(item, index) in list">
<!-- 表单项有设置分组时 -->
<el-col v-if="item.group && item.list" :key="index" :span="item.group.span || span">
<el-row type="flex" style="flex-wrap: wrap;width: 100%;">
<!-- 表单分组标题 -->
<el-col :class="titleClass || 'eagle-form__group-title'" v-if="item.group.title" :span="24">{{ item.group.title || item.group }}</el-col>
<!-- 递归本组件 -->
<form-render :title-class="titleClass" :list="item.list" :value="value" :model="itemKey ? model[itemKey] || {} : model" @item-change="onItemChange" @form-item-change="onFormItemChange" :itemKey="item.group.key" @item-update="onItemUpdate"></form-render>
</el-row>
</el-col>
<!-- 正常无分组表单项 -->
<el-col v-else :span="item.span || span" :key="index">
<el-form-item :label="item.label" :label-width="item.labelWidth || '120px'" :prop="item.fullKey" :rules="item.rules">
<!-- 自定义组件 -->
<component :is="item.type" :value="itemValue(item)" @input="v => onInput({ value: v, item })" v-on="bindItemEvent(item)"></component>
</el-form-item>
</el-col>
</template>
</el-row>
</template>
<script>
export default {
name: 'form-render',
props: {
list: Array,
model: Object,
value: Object,
itemKey: String,
titleClass: String,
contentClass: String,
span: Number,
},
methods: {
/**
* @description 根据表单项的key查询该值
* @param {Object} item 表单项配置
* @returns {Any} 返回值
*/
itemValue(item) {
if (this.itemKey) { // 如果存在itemKey,即当前项位于嵌套分组内,查询分组名下对应key的值
const groupItem = this.model[this.itemKey] || {};
return groupItem[item.key];
} else { // 否则即意味着不在分组内,直接查询model下对应key的值
return this.model[item.key];
}
},
/**
* @description 组件有值输入时的事件
* @param {Object} data { value => 组件值; item => 表单项配置 }
*/
onInput({ value, item }) {
if (this.itemKey) {
this.$emit('item-change', { [this.itemKey]: { ...this.model[this.itemKey], [item.key]: value } });
} else {
this.$emit('item-change', { [item.key]: value });
}
this.$emit('form-item-change', { [item.fullKey]: value });
},
/**
* @description 当表单项有改动时的事件
* @param {Any} 表单项值
*/
onItemChange(value) {
if (this.itemKey) {
this.$emit('item-change', { [this.itemKey]: { ...this.model[this.itemKey], ...value } });
} else {
this.$emit('item-change', value);
}
},
/**
* @description 当表单项校验值有改动时的事件
* @param {Any} 表单项校验值
*/
onFormItemChange(value) {
this.$emit('form-item-change', value);
},
/**
* @description 当表单项有手动更新时的事件
* @param {Any} 表单项值
*/
onItemUpdate(value) {
this.$emit('item-update', value);
},
/**
* @description 绑定表单项事件
* @param {Object} item 表单项配置
* @returns {Function} 事件函数
*/
bindItemEvent(item) {
if (item.on) {
if (typeof item.on === 'function') {
return item.on({ model: this.value, update: e => this.$emit('item-update', e) });
} else {
return item.on
}
} else {
return undefined
}
},
}
}
</script>