eoss 0.1.0-alpha.39 → 0.1.0-alpha.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/0.js +1 -1
- package/lib/1.js +1 -1
- package/lib/10.js +1 -1
- package/lib/11.js +1 -1
- package/lib/12.js +1 -1
- package/lib/13.js +1 -1
- package/lib/14.js +1 -1
- package/lib/15.js +1 -1
- package/lib/16.js +1 -1
- package/lib/17.js +1 -1
- package/lib/18.js +1 -1
- package/lib/19.js +1 -1
- package/lib/20.js +1 -1
- package/lib/21.js +1 -1
- package/lib/22.js +1 -1
- package/lib/23.js +1 -1
- package/lib/24.js +1 -1
- package/lib/25.js +1 -1
- package/lib/26.js +1 -1
- package/lib/27.js +1 -1
- package/lib/28.js +1 -1
- package/lib/29.js +1 -1
- package/lib/3.js +1 -1
- package/lib/30.js +1 -1
- package/lib/31.js +1 -1
- package/lib/32.js +1 -1
- package/lib/33.js +1 -1
- package/lib/34.js +1 -1
- package/lib/35.js +1 -1
- package/lib/36.js +1 -1
- package/lib/37.js +1 -1
- package/lib/38.js +1 -1
- package/lib/39.js +1 -1
- package/lib/4.js +1 -1
- package/lib/40.js +1 -1
- package/lib/41.js +1 -1
- package/lib/42.js +1 -1
- package/lib/43.js +1 -1
- package/lib/44.js +1 -1
- package/lib/45.js +1 -1
- package/lib/46.js +1 -1
- package/lib/47.js +1 -1
- package/lib/48.js +1 -1
- package/lib/49.js +1 -1
- package/lib/5.js +1 -1
- package/lib/50.js +1 -1
- package/lib/51.js +1 -1
- package/lib/52.js +1 -1
- package/lib/53.js +1 -1
- package/lib/54.js +1 -1
- package/lib/55.js +1 -1
- package/lib/56.js +1 -1
- package/lib/57.js +1 -1
- package/lib/58.js +1 -1
- package/lib/59.js +1 -1
- package/lib/6.js +1 -1
- package/lib/60.js +1 -1
- package/lib/61.js +1 -1
- package/lib/62.js +1 -1
- package/lib/63.js +1 -1
- package/lib/64.js +1 -1
- package/lib/65.js +1 -1
- package/lib/66.js +1 -1
- package/lib/67.js +1 -1
- package/lib/68.js +1 -1
- package/lib/69.js +1 -1
- package/lib/7.js +1 -1
- package/lib/70.js +1 -1
- package/lib/71.js +1 -1
- package/lib/72.js +1 -1
- package/lib/73.js +1 -1
- package/lib/74.js +1 -1
- package/lib/75.js +1 -1
- package/lib/76.js +1 -1
- package/lib/77.js +1 -1
- package/lib/78.js +1 -1
- package/lib/79.js +1 -1
- package/lib/8.js +1 -1
- package/lib/80.js +1 -1
- package/lib/81.js +1 -1
- package/lib/9.js +1 -1
- package/lib/account-login.js +837 -862
- package/lib/alert.js +2 -2
- package/lib/aside.js +2 -2
- package/lib/audit-trajectory.js +4 -4
- package/lib/autocomplete.js +1813 -1988
- package/lib/avatar.js +2 -2
- package/lib/backtop.js +2 -2
- package/lib/badge.js +2 -2
- package/lib/breadcrumb-item.js +4 -4
- package/lib/breadcrumb.js +4 -4
- package/lib/button-group.js +4 -4
- package/lib/button.js +2 -2
- package/lib/ca-login.js +837 -862
- package/lib/calendar.js +839 -864
- package/lib/card.js +2 -2
- package/lib/carousel-item.js +846 -871
- package/lib/carousel.js +839 -864
- package/lib/cascader-panel.js +852 -877
- package/lib/cascader.js +2048 -2223
- package/lib/checkbox-button.js +4 -4
- package/lib/checkbox-group.js +859 -884
- package/lib/checkbox.js +4 -4
- package/lib/col.js +2 -2
- package/lib/collapse-item.js +1040 -1065
- package/lib/collapse.js +1040 -1065
- package/lib/color-picker.js +972 -1122
- package/lib/container.js +2 -2
- package/lib/cron.js +12 -12
- package/lib/data-table.js +843 -868
- package/lib/date-picker.js +10520 -10695
- package/lib/descriptions-item.js +4 -4
- package/lib/descriptions.js +4 -4
- package/lib/dialog.js +837 -862
- package/lib/divider.js +2 -2
- package/lib/drawer.js +2 -2
- package/lib/dropdown-item.js +4 -4
- package/lib/dropdown-menu.js +974 -1124
- package/lib/dropdown.js +841 -866
- package/lib/email-login.js +837 -862
- package/lib/empty.js +2 -2
- package/lib/eoss.common.js +4023 -2668
- package/lib/flip.js +2 -2
- package/lib/flow-group.js +853 -878
- package/lib/flow.js +868 -893
- package/lib/flows.js +854 -879
- package/lib/footer.js +2 -2
- package/lib/form-item.js +860 -885
- package/lib/form.js +933 -950
- package/lib/guide.js +2 -2
- package/lib/header.js +2 -2
- package/lib/icon.js +837 -862
- package/lib/icons.js +2 -2
- package/lib/image-viewer.js +837 -862
- package/lib/image.js +4 -4
- package/lib/index.js +1 -1
- package/lib/infinite-scroll.js +2 -2
- package/lib/input-number.js +6 -6
- package/lib/input.js +839 -864
- package/lib/link.js +2 -2
- package/lib/loading.js +2 -2
- package/lib/login.js +867 -891
- package/lib/lowcode-view.js +1843 -1185
- package/lib/lowcode.js +3050 -1569
- package/lib/main.js +970 -988
- package/lib/marquee.js +837 -862
- package/lib/menu-item-group.js +15 -15
- package/lib/menu-item.js +6 -6
- package/lib/menu.js +2227 -2368
- package/lib/message-box.js +843 -868
- package/lib/message.js +839 -864
- package/lib/notification.js +861 -886
- package/lib/option-group.js +4 -4
- package/lib/option.js +839 -864
- package/lib/page-header.js +2 -2
- package/lib/pagination.js +839 -864
- package/lib/phone-login.js +847 -866
- package/lib/popconfirm.js +4 -4
- package/lib/popover.js +1831 -2006
- package/lib/process-config.js +839 -864
- package/lib/process-module.js +846 -871
- package/lib/process-rule.js +905 -930
- package/lib/progress.js +2 -2
- package/lib/qr-code.js +4 -4
- package/lib/qrcode-login.js +839 -864
- package/lib/radio-button.js +4 -4
- package/lib/radio-group.js +850 -875
- package/lib/radio.js +4 -4
- package/lib/rate.js +837 -862
- package/lib/retrial-auth.js +837 -862
- package/lib/row.js +2 -2
- package/lib/scrollbar.js +839 -864
- package/lib/select.js +2139 -2314
- package/lib/selector-panel.js +940 -965
- package/lib/selector.js +852 -877
- package/lib/slider.js +4 -4
- package/lib/step.js +32 -32
- package/lib/steps.js +874 -899
- package/lib/submenu.js +1269 -1385
- package/lib/switch.js +839 -864
- package/lib/tab-pane.js +4 -4
- package/lib/table-column.js +840 -865
- package/lib/table.js +1825 -2000
- package/lib/tabs.js +846 -871
- package/lib/tag.js +2 -2
- package/lib/theme-chalk/fonts/iconfont.ttf +0 -0
- package/lib/theme-chalk/fonts/iconfont.woff +0 -0
- package/lib/theme-chalk/index.css +1 -1
- package/lib/theme-chalk/lowcode.css +1 -1
- package/lib/time-picker.js +6471 -6646
- package/lib/time-select.js +5039 -5214
- package/lib/timeline-item.js +2 -2
- package/lib/timeline.js +2 -2
- package/lib/tips.js +837 -862
- package/lib/toolbar.js +4 -4
- package/lib/tooltip.js +1813 -1988
- package/lib/transfer.js +837 -862
- package/lib/tree-group.js +853 -878
- package/lib/tree.js +1026 -1051
- package/lib/update-history.js +4 -4
- package/lib/upload.js +859 -884
- package/lib/wujie.js +841 -866
- package/package.json +1 -1
- package/packages/flow-group/src/main.vue +2 -2
- package/packages/form/src/form-item-render.vue +1 -0
- package/packages/form/src/form-item.vue +12 -6
- package/packages/form/src/form.vue +5 -5
- package/packages/login/src/login.vue +1 -0
- package/packages/lowcode/src/attribute/function.vue +28 -9
- package/packages/lowcode/src/attribute/props.vue +202 -0
- package/packages/lowcode/src/attribute/styles.vue +79 -5
- package/packages/lowcode/src/attribute.vue +61 -4
- package/packages/lowcode/src/canvas.vue +159 -2
- package/packages/lowcode/src/form-render.vue +305 -0
- package/packages/lowcode/src/lowcode.vue +33 -13
- package/packages/lowcode/src/modules.vue +53 -37
- package/packages/lowcode/src/render.vue +80 -25
- package/packages/lowcode/src/util/components.js +100 -0
- package/packages/lowcode/src/util/props-util.js +67 -0
- package/packages/lowcode/src/util/source-generator.js +69 -9
- package/packages/lowcode/src/util/source-parser.js +64 -10
- package/packages/lowcode-view/src/render.vue +48 -18
- package/packages/main/src/components/userinfo.vue +0 -1
- package/packages/menu/src/menu-item-group.vue +1 -1
- package/packages/menu/src/mixins.js +8 -4
- package/packages/menu/src/submenu.vue +35 -5
- package/packages/phone-login/src/phone-login.vue +5 -2
- package/packages/theme-chalk/dist/fonts/iconfont.ttf +0 -0
- package/packages/theme-chalk/dist/fonts/iconfont.woff +0 -0
- package/packages/theme-chalk/src/fonts/iconfont.ttf +0 -0
- package/packages/theme-chalk/src/fonts/iconfont.woff +0 -0
- package/packages/theme-chalk/src/lowcode.scss +21 -2
- package/src/index.js +336 -336
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 节点 props 定义数组与取值转换工具
|
|
3
|
+
*
|
|
4
|
+
* 节点 props 存定义数组:[{ name, type, default?, options?, value? }],
|
|
5
|
+
* value 仅在用户改动后写入条目;字符串取值支持 {{变量名}} 语法
|
|
6
|
+
* 引用页面 data 中定义的变量(整体匹配按变量绑定,局部匹配按插值)
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/** 整体匹配 {{expr}} */
|
|
10
|
+
const FULL_VAR = /^\{\{([\s\S]+)\}\}$/;
|
|
11
|
+
/** 局部匹配 {{expr}} */
|
|
12
|
+
const PART_VAR = /\{\{([\s\S]+?)\}\}/g;
|
|
13
|
+
|
|
14
|
+
/** 按点路径从 data 中取变量值 */
|
|
15
|
+
function lookup(data, expr) {
|
|
16
|
+
if (!data || typeof data !== 'object') return undefined;
|
|
17
|
+
return expr.split('.').reduce((cur, key) => {
|
|
18
|
+
if (cur === undefined || cur === null) return undefined;
|
|
19
|
+
return cur[key];
|
|
20
|
+
}, data);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** 解析字符串取值中的 {{变量}} 引用;非字符串原样返回 */
|
|
24
|
+
export function resolvePropValue(raw, data) {
|
|
25
|
+
if (typeof raw !== 'string' || raw.indexOf('{{') === -1) return raw;
|
|
26
|
+
const full = FULL_VAR.exec(raw);
|
|
27
|
+
if (full) return lookup(data, full[1].trim());
|
|
28
|
+
return raw.replace(PART_VAR, (all, expr) => {
|
|
29
|
+
const val = lookup(data, expr.trim());
|
|
30
|
+
return val === undefined || val === null ? '' : val;
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** 按名读取条目原始取值(value 优先、其次 default);兼容历史对象形态 */
|
|
35
|
+
export function getPropRaw(props, name) {
|
|
36
|
+
if (!props) return undefined;
|
|
37
|
+
if (!Array.isArray(props)) return props[name];
|
|
38
|
+
const item = props.find((p) => p && p.name === name);
|
|
39
|
+
if (!item) return undefined;
|
|
40
|
+
return item.value !== undefined ? item.value : item.default;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* 定义数组 → 组件 v-bind 用的取值对象;
|
|
45
|
+
* 兼容历史对象形态 props(原样透传,跳过 v- 键)
|
|
46
|
+
*/
|
|
47
|
+
export function propsToObject(props, data) {
|
|
48
|
+
if (!props) return {};
|
|
49
|
+
if (!Array.isArray(props)) {
|
|
50
|
+
const result = {};
|
|
51
|
+
Object.keys(props).forEach((key) => {
|
|
52
|
+
if (key.startsWith('v-')) return;
|
|
53
|
+
result[key] = props[key];
|
|
54
|
+
});
|
|
55
|
+
return result;
|
|
56
|
+
}
|
|
57
|
+
const result = {};
|
|
58
|
+
props.forEach((item) => {
|
|
59
|
+
if (!item || !item.name) return;
|
|
60
|
+
const raw = item.value !== undefined ? item.value : item.default;
|
|
61
|
+
if (raw === undefined) return;
|
|
62
|
+
const val = resolvePropValue(raw, data);
|
|
63
|
+
if (val === undefined) return;
|
|
64
|
+
result[item.name] = val;
|
|
65
|
+
});
|
|
66
|
+
return result;
|
|
67
|
+
}
|
|
@@ -80,12 +80,37 @@ function escapeAttr(val) {
|
|
|
80
80
|
.replace(/"/g, '"');
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
+
/** 单个 prop 属性串:{{var}} 整体匹配输出绑定表达式,其余按类型输出 */
|
|
84
|
+
function genPropAttr(key, val) {
|
|
85
|
+
if (typeof val === 'string') {
|
|
86
|
+
const full = /^\{\{([\s\S]+)\}\}$/.exec(val);
|
|
87
|
+
if (full) {
|
|
88
|
+
return ' :' + key + '="' + full[1].trim() + '"';
|
|
89
|
+
}
|
|
90
|
+
return ' ' + key + '="' + val + '"';
|
|
91
|
+
}
|
|
92
|
+
if (typeof val === 'boolean' || typeof val === 'number') {
|
|
93
|
+
return ' :' + key + '="' + val + '"';
|
|
94
|
+
}
|
|
95
|
+
// 复杂值用绑定语法输出:单引号属性 + 紧凑 JSON
|
|
96
|
+
return ' :' + key + "='" + JSON.stringify(val).replace(/'/g, ''') + "'";
|
|
97
|
+
}
|
|
98
|
+
|
|
83
99
|
/** 生成节点的 props 属性串 */
|
|
84
100
|
function genProps(node) {
|
|
85
101
|
const props = node.props;
|
|
86
102
|
if (!props) {
|
|
87
103
|
return '';
|
|
88
104
|
}
|
|
105
|
+
// 定义数组形态:仅输出值被改动过的条目(value 字段)
|
|
106
|
+
if (Array.isArray(props)) {
|
|
107
|
+
return props.reduce((attrs, item) => {
|
|
108
|
+
if (!item || !item.name || item.value === undefined) {
|
|
109
|
+
return attrs;
|
|
110
|
+
}
|
|
111
|
+
return attrs + genPropAttr(item.name, item.value);
|
|
112
|
+
}, '');
|
|
113
|
+
}
|
|
89
114
|
return Object.keys(props).reduce((attrs, key) => {
|
|
90
115
|
const val = props[key];
|
|
91
116
|
if (val === undefined) {
|
|
@@ -186,6 +211,14 @@ function componentName(name) {
|
|
|
186
211
|
});
|
|
187
212
|
}
|
|
188
213
|
|
|
214
|
+
/** EsButton → es-button 形式的模板标签名(html 小写标签保持不变) */
|
|
215
|
+
function tagName(name) {
|
|
216
|
+
return String(name)
|
|
217
|
+
.replace(/([A-Z])/g, '-$1')
|
|
218
|
+
.toLowerCase()
|
|
219
|
+
.replace(/^-/, '');
|
|
220
|
+
}
|
|
221
|
+
|
|
189
222
|
/** 递归收集节点树中的所有脚本依赖 */
|
|
190
223
|
function collectScripts(node, scripts) {
|
|
191
224
|
if (!node) return;
|
|
@@ -227,7 +260,7 @@ export function genNode(node, indent) {
|
|
|
227
260
|
return '';
|
|
228
261
|
}
|
|
229
262
|
const pad = new Array(indent + 1).join(INDENT);
|
|
230
|
-
const
|
|
263
|
+
const tag = tagName(node.name || 'div');
|
|
231
264
|
|
|
232
265
|
// 节点 id 以 data-id 输出,源码编辑后能原样解析回来
|
|
233
266
|
const idAttr = node.id ? ' data-id="' + node.id + '"' : '';
|
|
@@ -245,23 +278,50 @@ export function genNode(node, indent) {
|
|
|
245
278
|
const vText = node.directives && node.directives['text'];
|
|
246
279
|
|
|
247
280
|
if (!children.length && !vText) {
|
|
248
|
-
lines.push(pad + '<' +
|
|
281
|
+
lines.push(pad + '<' + tag + attrStr + '></' + tag + '>');
|
|
249
282
|
return lines.join('\n');
|
|
250
283
|
}
|
|
251
|
-
lines.push(pad + '<' +
|
|
284
|
+
lines.push(pad + '<' + tag + attrStr + '>');
|
|
252
285
|
if (vText) {
|
|
253
286
|
// v-text 属性转换为 {{xxx}} 形式
|
|
254
287
|
lines.push(pad + INDENT + '{{' + vText + '}}');
|
|
255
|
-
} else if (children.length) {
|
|
256
|
-
// 子节点继续递归下钻
|
|
257
|
-
children.forEach((child) => {
|
|
258
|
-
lines.push(genNode(child, indent + 1));
|
|
259
|
-
});
|
|
260
288
|
}
|
|
261
|
-
|
|
289
|
+
// 子节点继续递归下钻;带 formItem 标记的表单控件子节点输出时
|
|
290
|
+
// 包 es-form-item(JSON 不存包裹节点,源码与真实应用结构一一对应)
|
|
291
|
+
children.forEach((child) => {
|
|
292
|
+
lines.push(genChildNode(child, indent + 1));
|
|
293
|
+
});
|
|
294
|
+
lines.push(pad + '</' + tag + '>');
|
|
262
295
|
return lines.join('\n');
|
|
263
296
|
}
|
|
264
297
|
|
|
298
|
+
/** 生成子节点:表单控件(带 formItem)包 es-form-item 包裹层,其余直接生成 */
|
|
299
|
+
function genChildNode(child, indent) {
|
|
300
|
+
if (!child) {
|
|
301
|
+
return '';
|
|
302
|
+
}
|
|
303
|
+
if (!child.formItem) {
|
|
304
|
+
return genNode(child, indent);
|
|
305
|
+
}
|
|
306
|
+
const pad = new Array(indent + 1).join(INDENT);
|
|
307
|
+
const label = child.formItem.label || '';
|
|
308
|
+
const prop = child.formItem.prop || '';
|
|
309
|
+
// 宽度输出在包裹层:form-item 是列布局单元,拖宽占多列才能在真实应用生效;
|
|
310
|
+
// 内层控件不重复携带 width(画布上宽度同样作用于 es-form-item 根)
|
|
311
|
+
const width = child.style && child.style.width;
|
|
312
|
+
const styleAttr = width ? genStyle({ style: { width } }) : '';
|
|
313
|
+
let inner = child;
|
|
314
|
+
if (width) {
|
|
315
|
+
inner = { ...child, style: { ...child.style } };
|
|
316
|
+
delete inner.style.width;
|
|
317
|
+
}
|
|
318
|
+
return (
|
|
319
|
+
pad + '<es-form-item label="' + escapeAttr(label) + '" prop="' + escapeAttr(prop) + '"' + styleAttr + '>\n' +
|
|
320
|
+
genNode(inner, indent + 1) + '\n' +
|
|
321
|
+
pad + '</es-form-item>'
|
|
322
|
+
);
|
|
323
|
+
}
|
|
324
|
+
|
|
265
325
|
/**
|
|
266
326
|
* 生成 methods/computed/watch 等选项块
|
|
267
327
|
* @param {string} name 选项名,如 computed 会生成计算属性 getter
|
|
@@ -76,6 +76,20 @@ function parseAttrs(str) {
|
|
|
76
76
|
return attrs;
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
+
/** 写入 props 定义条目(props 为定义数组,同名覆盖) */
|
|
80
|
+
function pushProp(node, name, type, value) {
|
|
81
|
+
if (!Array.isArray(node.props)) {
|
|
82
|
+
node.props = [];
|
|
83
|
+
}
|
|
84
|
+
const found = node.props.find((p) => p && p.name === name);
|
|
85
|
+
if (found) {
|
|
86
|
+
found.type = type;
|
|
87
|
+
found.value = value;
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
node.props.push({ name, type, value });
|
|
91
|
+
}
|
|
92
|
+
|
|
79
93
|
/** 属性列表 → 节点字段(attrs / props / directives / events / style) */
|
|
80
94
|
function applyAttrs(node, attrs) {
|
|
81
95
|
attrs.forEach((attr) => {
|
|
@@ -108,26 +122,24 @@ function applyAttrs(node, attrs) {
|
|
|
108
122
|
return;
|
|
109
123
|
}
|
|
110
124
|
if (name.charAt(0) === ':') {
|
|
111
|
-
node.props = node.props || {};
|
|
112
125
|
const key = name.slice(1);
|
|
113
126
|
const trimmed = String(value).trim();
|
|
114
|
-
// 单引号且以 [ / { 开头:生成器的复杂值载体(紧凑 JSON
|
|
115
|
-
// 双引号仍按表达式字符串处理,保持历史语义
|
|
127
|
+
// 单引号且以 [ / { 开头:生成器的复杂值载体(紧凑 JSON),还原为真实数组/对象
|
|
116
128
|
if (attr.quote === "'" && /^[[{]/.test(trimmed)) {
|
|
117
129
|
try {
|
|
118
|
-
node
|
|
130
|
+
pushProp(node, key, 'text', new Function('return (' + trimmed + ');')());
|
|
119
131
|
} catch (e) {
|
|
120
|
-
node
|
|
132
|
+
pushProp(node, key, 'text', String(value));
|
|
121
133
|
}
|
|
122
134
|
return;
|
|
123
135
|
}
|
|
124
|
-
//
|
|
136
|
+
// 数字/布尔直接还原类型;其它绑定表达式记为 {{var}} 变量引用
|
|
125
137
|
if (/^-?\d+(\.\d+)?$/.test(trimmed)) {
|
|
126
|
-
node
|
|
138
|
+
pushProp(node, key, 'number', Number(trimmed));
|
|
127
139
|
} else if (trimmed === 'true' || trimmed === 'false') {
|
|
128
|
-
node
|
|
140
|
+
pushProp(node, key, 'switch', trimmed === 'true');
|
|
129
141
|
} else {
|
|
130
|
-
node
|
|
142
|
+
pushProp(node, key, 'text', '{{' + trimmed + '}}');
|
|
131
143
|
}
|
|
132
144
|
return;
|
|
133
145
|
}
|
|
@@ -153,7 +165,7 @@ export function migrateDirectives(node) {
|
|
|
153
165
|
if (!node || typeof node !== 'object') {
|
|
154
166
|
return node;
|
|
155
167
|
}
|
|
156
|
-
if (node.props) {
|
|
168
|
+
if (node.props && !Array.isArray(node.props)) {
|
|
157
169
|
Object.keys(node.props).forEach((key) => {
|
|
158
170
|
if (key.startsWith('v-')) {
|
|
159
171
|
const dirKey = key.slice(2);
|
|
@@ -234,9 +246,51 @@ export function parseTemplateNodes(inner) {
|
|
|
234
246
|
if (stack.length) {
|
|
235
247
|
throw new Error('标签未正确闭合:<' + stack[stack.length - 1].name + '>');
|
|
236
248
|
}
|
|
249
|
+
normalizeFormItems(roots);
|
|
237
250
|
return roots;
|
|
238
251
|
}
|
|
239
252
|
|
|
253
|
+
/**
|
|
254
|
+
* es-form-item 包裹结构 → 控件节点 + formItem 标记(genChildNode 的逆操作):
|
|
255
|
+
* JSON 不存包裹节点,label/prop 记在内层控件节点的 formItem 上,
|
|
256
|
+
* 画布由 form-render 渲染时重新生成包裹层;原地递归处理整棵节点树
|
|
257
|
+
* @param {Array} nodes 节点数组
|
|
258
|
+
* @returns {Array} 同一个节点数组
|
|
259
|
+
*/
|
|
260
|
+
export function normalizeFormItems(nodes) {
|
|
261
|
+
nodes.forEach((node) => {
|
|
262
|
+
if (!node.children || !node.children.length) {
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
node.children = node.children.map((child) => {
|
|
266
|
+
if (
|
|
267
|
+
child.name === 'es-form-item' &&
|
|
268
|
+
child.children &&
|
|
269
|
+
child.children.length === 1
|
|
270
|
+
) {
|
|
271
|
+
const inner = child.children[0];
|
|
272
|
+
const meta = { ...(child.attrs || {}), ...(child.props || {}) };
|
|
273
|
+
inner.formItem = {
|
|
274
|
+
label: meta.label !== undefined ? String(meta.label) : '',
|
|
275
|
+
prop: meta.prop !== undefined ? String(meta.prop) : ''
|
|
276
|
+
};
|
|
277
|
+
// 包裹层宽度还原到控件节点 style.width(画布上作用于 es-form-item 根,
|
|
278
|
+
// 与 genChildNode 输出位置互逆)
|
|
279
|
+
if (child.style && child.style.width) {
|
|
280
|
+
inner.style = { ...(inner.style || {}), width: child.style.width };
|
|
281
|
+
}
|
|
282
|
+
if (!inner.description) {
|
|
283
|
+
inner.description = inner.formItem.label;
|
|
284
|
+
}
|
|
285
|
+
return inner;
|
|
286
|
+
}
|
|
287
|
+
return child;
|
|
288
|
+
});
|
|
289
|
+
normalizeFormItems(node.children);
|
|
290
|
+
});
|
|
291
|
+
return nodes;
|
|
292
|
+
}
|
|
293
|
+
|
|
240
294
|
/** 给节点树回填 id(有 id 的保留,没有的按路径生成稳定 id) */
|
|
241
295
|
let idSeed = 0;
|
|
242
296
|
function assignIds(nodes) {
|
|
@@ -20,16 +20,19 @@
|
|
|
20
20
|
: true
|
|
21
21
|
"
|
|
22
22
|
>
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
23
|
+
<!-- 不用 v-if/v-else 包裹:children 为空时假分支的空注释/文本节点
|
|
24
|
+
会被 EsForm 等组件误判默认插槽有内容,导致 slot fallback 不渲染 -->
|
|
25
|
+
<!-- 子节点统一递归渲染;表单控件子节点(带 formItem 标记)复用
|
|
26
|
+
编辑器同一个 form-render(es-form-item 包裹层渲染时生成,无选中手柄) -->
|
|
27
|
+
<component
|
|
28
|
+
:is="childRender(child)"
|
|
29
|
+
v-for="child in newNode.children"
|
|
30
|
+
:key="child.id"
|
|
31
|
+
:node="child"
|
|
32
|
+
:page="page"
|
|
33
|
+
:drag="false"
|
|
34
|
+
/>
|
|
35
|
+
<template v-for="t in slotTexts">{{ t }}</template>
|
|
33
36
|
</component>
|
|
34
37
|
<template v-if="drag">
|
|
35
38
|
<div class="es-lowcode__handles">
|
|
@@ -82,10 +85,13 @@
|
|
|
82
85
|
|
|
83
86
|
<script>
|
|
84
87
|
import Frame from './Iframe.vue';
|
|
88
|
+
import { propsToObject } from 'eoss/packages/lowcode/src/util/props-util.js';
|
|
89
|
+
import FormRender from 'eoss/packages/lowcode/src/form-render.vue';
|
|
85
90
|
import EsButton from 'eoss/packages/button';
|
|
91
|
+
|
|
86
92
|
export default {
|
|
87
93
|
name: 'Render',
|
|
88
|
-
components: { Frame, EsButton },
|
|
94
|
+
components: { Frame, FormRender, EsButton },
|
|
89
95
|
props: {
|
|
90
96
|
node: {
|
|
91
97
|
type: Object,
|
|
@@ -206,6 +212,12 @@ export default {
|
|
|
206
212
|
}
|
|
207
213
|
return textExpr;
|
|
208
214
|
},
|
|
215
|
+
/**
|
|
216
|
+
* 页面 data 变量:供 props 中 {{var}} 引用解析
|
|
217
|
+
*/
|
|
218
|
+
pageData() {
|
|
219
|
+
return (this.page && this.page.data) || {};
|
|
220
|
+
},
|
|
209
221
|
/**
|
|
210
222
|
* 过滤掉 Vue 指令(v-xxx)的 props,避免它们作为普通属性传递给组件
|
|
211
223
|
* 指令统一存在 directives 字段,这里仅兼容历史数据中混入 props 的 v- 键
|
|
@@ -217,19 +229,37 @@ export default {
|
|
|
217
229
|
if (this.newNode.attrs) {
|
|
218
230
|
Object.assign(result, this.newNode.attrs);
|
|
219
231
|
}
|
|
220
|
-
// 合并组件 props
|
|
221
|
-
|
|
222
|
-
Object.keys(this.newNode.props).forEach((key) => {
|
|
223
|
-
if (key.startsWith('v-')) return;
|
|
224
|
-
result[key] = this.newNode.props[key];
|
|
225
|
-
});
|
|
226
|
-
}
|
|
232
|
+
// 合并组件 props:定义数组经 propsToObject 转取值对象(含 {{var}} 解析)
|
|
233
|
+
Object.assign(result, propsToObject(this.newNode.props, this.pageData));
|
|
227
234
|
return result;
|
|
235
|
+
},
|
|
236
|
+
/**
|
|
237
|
+
* 插槽文本:仅当无 children 时产出,
|
|
238
|
+
* 保证 EsForm 等组件在无字段时默认插槽为空、fallback 生效
|
|
239
|
+
*/
|
|
240
|
+
slotTexts() {
|
|
241
|
+
const node = this.newNode;
|
|
242
|
+
if (!node) {
|
|
243
|
+
return [];
|
|
244
|
+
}
|
|
245
|
+
const hasChildren =
|
|
246
|
+
Array.isArray(node.children) && node.children.length > 0;
|
|
247
|
+
if (hasChildren) {
|
|
248
|
+
return [];
|
|
249
|
+
}
|
|
250
|
+
return [this.resolvedText || node.description || ''];
|
|
228
251
|
}
|
|
229
252
|
},
|
|
230
253
|
mounted() {},
|
|
231
254
|
beforeDestroy() {},
|
|
232
255
|
methods: {
|
|
256
|
+
/**
|
|
257
|
+
* 子节点渲染器:表单控件子节点(带 formItem 标记)由 form-render 渲染,
|
|
258
|
+
* 其余走通用 Render(与编辑器 render.vue 同一判定)
|
|
259
|
+
*/
|
|
260
|
+
childRender(child) {
|
|
261
|
+
return child && child.formItem ? 'FormRender' : 'Render';
|
|
262
|
+
},
|
|
233
263
|
/**
|
|
234
264
|
* 处理组件大小调整开始事件
|
|
235
265
|
* @param event 指针事件对象
|
|
@@ -58,15 +58,19 @@ export default {
|
|
|
58
58
|
if (!this._colorCache) {
|
|
59
59
|
this._colorCache = {};
|
|
60
60
|
}
|
|
61
|
-
|
|
62
|
-
const key = Array.isArray(this.iconColors)
|
|
61
|
+
// 缓存键为颜色槽位;缓存值仅依赖 iconColors 与槽位(iconColors 变化由 watcher 清缓存)
|
|
62
|
+
const key = Array.isArray(this.iconColors)
|
|
63
|
+
? `index_${index % this.iconColors.length}`
|
|
64
|
+
: 'single_color';
|
|
63
65
|
|
|
64
66
|
if (!this._colorCache[key]) {
|
|
65
|
-
const bgColor = Array.isArray(this.iconColors)
|
|
67
|
+
const bgColor = Array.isArray(this.iconColors)
|
|
68
|
+
? this.iconColors[index % this.iconColors.length]
|
|
69
|
+
: this.iconColors;
|
|
66
70
|
this._colorCache[key] = {
|
|
67
71
|
'--icon-bg-color': bgColor,
|
|
68
72
|
'--icon-color': '#fff',
|
|
69
|
-
'--icon-font-size':
|
|
73
|
+
'--icon-font-size': '12px'
|
|
70
74
|
};
|
|
71
75
|
}
|
|
72
76
|
|
|
@@ -151,7 +151,7 @@
|
|
|
151
151
|
:close-icon="closeIcon"
|
|
152
152
|
:isFourthTabs="isFourthTabs"
|
|
153
153
|
:iconColors="iconColors"
|
|
154
|
-
:iconColor="getColor(index)"
|
|
154
|
+
:iconColor="getColor(index, item)"
|
|
155
155
|
>
|
|
156
156
|
</component>
|
|
157
157
|
</slot>
|
|
@@ -310,10 +310,10 @@ export default {
|
|
|
310
310
|
return this.collapse ? 'es-zoom-in-left' : 'es-zoom-in-top';
|
|
311
311
|
},
|
|
312
312
|
opened() {
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
return
|
|
313
|
+
// 展开状态统一由 rootMenu.openedMenus 驱动,
|
|
314
|
+
// open 属性仅作为默认展开的初始值(见 syncOpenProp),不参与计算,
|
|
315
|
+
// 否则 open 为 true 时会短路导致点击无法折叠
|
|
316
|
+
return !!this.index && this.rootMenu.openedMenus.indexOf(this.index) > -1;
|
|
317
317
|
},
|
|
318
318
|
active() {
|
|
319
319
|
let isActive = false;
|
|
@@ -417,6 +417,15 @@ export default {
|
|
|
417
417
|
});
|
|
418
418
|
}
|
|
419
419
|
},
|
|
420
|
+
open() {
|
|
421
|
+
this.syncOpenProp();
|
|
422
|
+
},
|
|
423
|
+
collapse(val) {
|
|
424
|
+
// 整菜单收起会清空 openedMenus,取消收起后按 open 属性恢复默认展开
|
|
425
|
+
if (!val) {
|
|
426
|
+
this.syncOpenProp();
|
|
427
|
+
}
|
|
428
|
+
},
|
|
420
429
|
iconColors() {
|
|
421
430
|
// 当iconColors变化时,清除缓存
|
|
422
431
|
this._colorCache = null;
|
|
@@ -456,6 +465,26 @@ export default {
|
|
|
456
465
|
};
|
|
457
466
|
},
|
|
458
467
|
methods: {
|
|
468
|
+
/**
|
|
469
|
+
* 同步 open 属性到 rootMenu.openedMenus:
|
|
470
|
+
* open 语义为“默认展开”,写入 openedMenus 后仍可被点击正常折叠/展开
|
|
471
|
+
*/
|
|
472
|
+
syncOpenProp() {
|
|
473
|
+
if (!this.index || this.collapse) {
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
476
|
+
const rootMenu = this.rootMenu;
|
|
477
|
+
const isOpened = rootMenu.openedMenus.indexOf(this.index) > -1;
|
|
478
|
+
if (this.open && !isOpened) {
|
|
479
|
+
// 默认展开直接写入 openedMenus,不走 openMenu 的 uniqueOpened 过滤:
|
|
480
|
+
// 嵌套子菜单内层先于外层 mounted,若走 openMenu,
|
|
481
|
+
// 外层展开时会把不在其 indexPath 上的内层默认展开过滤收起
|
|
482
|
+
rootMenu.openedMenus.push(this.index);
|
|
483
|
+
rootMenu.$nextTick(() => rootMenu.updated());
|
|
484
|
+
} else if (!this.open && isOpened) {
|
|
485
|
+
rootMenu.closeMenu(this.index);
|
|
486
|
+
}
|
|
487
|
+
},
|
|
459
488
|
handleCollapseToggle(value) {
|
|
460
489
|
if (value) {
|
|
461
490
|
this.initPopper();
|
|
@@ -567,6 +596,7 @@ export default {
|
|
|
567
596
|
this.parentMenu.addSubmenu(this);
|
|
568
597
|
this.rootMenu.addSubmenu(this);
|
|
569
598
|
this.initPopper();
|
|
599
|
+
this.syncOpenProp();
|
|
570
600
|
},
|
|
571
601
|
updated() {
|
|
572
602
|
this.$nextTick(() => {
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
<script>
|
|
66
66
|
import { getLoginCode } from 'eoss/src/config/api';
|
|
67
67
|
import { ajax } from 'eoss/src/utils/ajax';
|
|
68
|
-
|
|
68
|
+
import { loading, error } from 'eoss/src/utils/util';
|
|
69
69
|
import EsButton from 'eoss/packages/button';
|
|
70
70
|
import EsForm from 'eoss/packages/form';
|
|
71
71
|
import EsFormItem from 'eoss/packages/form-item';
|
|
@@ -274,6 +274,7 @@ export default {
|
|
|
274
274
|
* 处理提交
|
|
275
275
|
*/
|
|
276
276
|
handleSubmit() {
|
|
277
|
+
console.log('18086814030', this.$refs.loginForm);
|
|
277
278
|
this.$refs.loginForm &&
|
|
278
279
|
this.$refs.loginForm
|
|
279
280
|
.validate()
|
|
@@ -305,7 +306,9 @@ export default {
|
|
|
305
306
|
}
|
|
306
307
|
this.$emit('submit', this.formData);
|
|
307
308
|
})
|
|
308
|
-
.catch(() => {
|
|
309
|
+
.catch((e) => {
|
|
310
|
+
console.log('e', e);
|
|
311
|
+
});
|
|
309
312
|
},
|
|
310
313
|
/**
|
|
311
314
|
* 处理键盘事件
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -188,6 +188,20 @@
|
|
|
188
188
|
justify-content: flex-end;
|
|
189
189
|
}
|
|
190
190
|
}
|
|
191
|
+
@include e(props) {
|
|
192
|
+
color: #909399;
|
|
193
|
+
font-size: 12px;
|
|
194
|
+
line-height: 1.6;
|
|
195
|
+
@include m(tip) {
|
|
196
|
+
padding: 8px;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
code {
|
|
200
|
+
padding: 0 2px;
|
|
201
|
+
color: #606266;
|
|
202
|
+
background: #f5f7fa;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
191
205
|
@include e(styles) {
|
|
192
206
|
height: 100%;
|
|
193
207
|
}
|
|
@@ -269,6 +283,7 @@
|
|
|
269
283
|
}
|
|
270
284
|
&::after {
|
|
271
285
|
content: '';
|
|
286
|
+
display: block;
|
|
272
287
|
position: absolute;
|
|
273
288
|
top: 0;
|
|
274
289
|
left: 0;
|
|
@@ -295,16 +310,20 @@
|
|
|
295
310
|
}
|
|
296
311
|
@include e(modules) {
|
|
297
312
|
height: calc(100% - 32px);
|
|
298
|
-
padding-right: 8px;
|
|
299
|
-
padding-left: 8px;
|
|
300
313
|
.es-collapse {
|
|
301
314
|
border-top: none;
|
|
302
315
|
}
|
|
316
|
+
.es-tabs__header {
|
|
317
|
+
padding: 0 12px;
|
|
318
|
+
}
|
|
303
319
|
.es-tabs__nav-wrap {
|
|
304
320
|
&::after {
|
|
305
321
|
height: 1px;
|
|
306
322
|
}
|
|
307
323
|
}
|
|
324
|
+
.es-scrollbar__view {
|
|
325
|
+
padding: 8px;
|
|
326
|
+
}
|
|
308
327
|
@include m(item) {
|
|
309
328
|
display: flex;
|
|
310
329
|
flex-direction: column;
|