index.vue
4.32 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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
<style>
.eagle-form__flex-wrap {
display: flex;
flex-wrap: wrap;
width: 100%;
}
.eagle-form__group-title {
font-weight: bold;
padding: 15px 5px;
border-bottom: 1px solid #d9d9d9;
margin-bottom: 30px;
}
.eagle-form__group-content {
margin: 15px 0px;
}
</style>
<template>
<el-form ref="form" size="mini" :class="formClass" :model="formModel" :label-width="labelWidth" :label-position="labelPosition || labelWidth ? 'right' : 'top'">
<form-render :title-class="titleClass" :content-class="contentClass" :item-class="itemClass" :group-class="groupClass"
:list="formList" :value="model" :model="model" :span="span" :type="type"
@item-change="onItemChange" @form-item-change="onFormItemChange" @item-update="onItemUpdate"
></form-render>
</el-form>
</template>
<script>
import FormRender from './form-render';
import { cloneDeep, set } from './util';
export default {
name: 'FormNew',
components: { FormRender },
props: {
value: Object,
list: Array,
formClass: String,
titleClass: String,
contentClass: String,
itemClass: String,
groupClass: String,
labelWidth: String,
labelPosition: String,
type: String,
span: {
type: Number,
default: 24
}
},
data() {
return {
model: {},
formModel: {},
formList: []
}
},
watch: {
value: {
handler(val = {}) {
this.model = val;
this.setFormModel(val)
},
immediate: true
},
list: {
handler(val) {
// 深度克隆传入的列表,避免原始值被修改
const newList = cloneDeep(this.list);
// 生成列表值的全路径key,即列表项为对象时,对象内的key与上一级的key合并作为全路径key
const generateFullKey = (list, parentKey) => {
list.forEach(item => {
if (item.group && item.list) {
if (item.group.key) {
item.fullKey = `${parentKey ? `${parentKey}-${item.group.key}` : item.group.key}`;
} else {
item.fullKey = parentKey || item.key;
}
generateFullKey(item.list, item.fullKey);
} else {
item.fullKey = `${parentKey ? `${parentKey}-${item.key}` : item.key}`;
}
});
};
generateFullKey(newList);
this.formList = newList;
},
immediate: true
}
},
methods: {
/**
* @description 表单项值变化
* @param {Object} item 表单项值对象
*/
onItemChange(item) {
this.$emit('input', { ...this.model, ...item });
},
/**
* @description 表单相校验值变化
* @param {Object} item 表单项校验值对象
*/
onFormItemChange(item) {
this.formModel = { ...this.formModel, ...item };
},
/**
* @description 校验表单
*/
validate() {
this.$refs.form.validate(valid => {
this.$emit("validate", valid, this.model);
});
},
/**
* @description 根据表单值设置表单校验值
* @param {Object} value 表单值
*/
setFormModel(value) {
let formModel = {};
// 递归深度解析表单值,将表单值扁平化为一层的对象并设置为表单校验值对象
const setFormModelValue = (list, parentKey) => {
list.forEach(item => {
item.fullKey = `${parentKey ? `${parentKey}-${item.key}` : item.key}`;
if (item.value instanceof Object) {
setFormModelValue(Object.keys(item.value).map(key => ({ key, value: item.value[key] })), item.fullKey);
} else {
formModel[item.fullKey] = item.value;
}
});
};
setFormModelValue(Object.keys(value).map(key => ({ key, value: value[key] })));
this.formModel = formModel;
},
/**
* @description 手动更新某一表单项的值
* @param {Object} param 需要更新的参数对象或者对象数组 { name => 表单项key,可嵌套; value => 更新的值 }
* @example { name: 'a.b.c', value: 123 }
* @example { name: 'd.0.e', value: ['f'] }
*/
onItemUpdate(param) {
this.$nextTick(() => {
const newModel = cloneDeep(this.model);
Object.entries(param).forEach(entry => {
set(newModel, entry[0], entry[1]);
});
this.$emit('input', newModel);
});
}
}
}
</script>