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
package/package.json
CHANGED
|
@@ -160,7 +160,7 @@
|
|
|
160
160
|
full
|
|
161
161
|
:key="index"
|
|
162
162
|
:autoId="true"
|
|
163
|
-
:show-
|
|
163
|
+
:show-default-buttons="false"
|
|
164
164
|
:closeDialog="false"
|
|
165
165
|
:display="activeName === String(indexs)"
|
|
166
166
|
:model="item.model"
|
|
@@ -308,7 +308,7 @@
|
|
|
308
308
|
></component>
|
|
309
309
|
<es-form
|
|
310
310
|
v-if="contents.type === 'form'"
|
|
311
|
-
:show-
|
|
311
|
+
:show-default-buttons="false"
|
|
312
312
|
ref="esFlowForm"
|
|
313
313
|
:showMsg="showMsg"
|
|
314
314
|
v-bind="
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
:style="itemStyle"
|
|
5
5
|
:class="[
|
|
6
6
|
{
|
|
7
|
-
|
|
7
|
+
'es-form-item--feedback': esForm && esForm.statusIcon,
|
|
8
8
|
'es-form--label-top': labelPosition === 'top',
|
|
9
9
|
'is-error': validateState === 'error',
|
|
10
10
|
'is-validating': validateState === 'validating',
|
|
@@ -110,7 +110,7 @@ export default {
|
|
|
110
110
|
* 标签宽度
|
|
111
111
|
*/
|
|
112
112
|
labelWidth: String,
|
|
113
|
-
|
|
113
|
+
|
|
114
114
|
/**
|
|
115
115
|
* 字段名,用于表单验证和数据绑定
|
|
116
116
|
*/
|
|
@@ -250,10 +250,10 @@ export default {
|
|
|
250
250
|
width: `${(this.span / 12) * 100}%`
|
|
251
251
|
};
|
|
252
252
|
}
|
|
253
|
-
const
|
|
254
|
-
if (
|
|
253
|
+
const columns = this.esForm.columns;
|
|
254
|
+
if (columns > 1) {
|
|
255
255
|
return {
|
|
256
|
-
width: `${100 /
|
|
256
|
+
width: `${100 / columns}%`
|
|
257
257
|
};
|
|
258
258
|
}
|
|
259
259
|
return {};
|
|
@@ -264,7 +264,13 @@ export default {
|
|
|
264
264
|
const labelWidth = this.labelWidth || form.labelWidth;
|
|
265
265
|
const label = this.label || this.$slots.label;
|
|
266
266
|
// 快速路径:无需计算样式
|
|
267
|
-
if (
|
|
267
|
+
if (
|
|
268
|
+
!label ||
|
|
269
|
+
this.labelPosition === 'top' ||
|
|
270
|
+
form.labelPosition === 'top' ||
|
|
271
|
+
form.inline
|
|
272
|
+
)
|
|
273
|
+
return {};
|
|
268
274
|
if (!this.labelWidth && this.isNested) return {};
|
|
269
275
|
|
|
270
276
|
// 构建样式对象
|
|
@@ -236,7 +236,7 @@ export default {
|
|
|
236
236
|
default: '120px'
|
|
237
237
|
},
|
|
238
238
|
// 列数
|
|
239
|
-
|
|
239
|
+
columns: {
|
|
240
240
|
type: Number,
|
|
241
241
|
default: 1
|
|
242
242
|
},
|
|
@@ -246,8 +246,8 @@ export default {
|
|
|
246
246
|
contents: Array,
|
|
247
247
|
//按钮组配置
|
|
248
248
|
buttons: [Object, Array],
|
|
249
|
-
//
|
|
250
|
-
|
|
249
|
+
// 显示配置生成的默认按钮组(buttons prop / contents 中 buttons 条目)
|
|
250
|
+
showDefaultButtons: {
|
|
251
251
|
type: Boolean,
|
|
252
252
|
default: true
|
|
253
253
|
},
|
|
@@ -301,7 +301,7 @@ export default {
|
|
|
301
301
|
type: Boolean,
|
|
302
302
|
default: true
|
|
303
303
|
},
|
|
304
|
-
//
|
|
304
|
+
// 是否显示按钮区容器(含 buttons 插槽)
|
|
305
305
|
showButtons: {
|
|
306
306
|
type: Boolean,
|
|
307
307
|
default: true
|
|
@@ -329,7 +329,7 @@ export default {
|
|
|
329
329
|
// 表单按钮
|
|
330
330
|
formButtons() {
|
|
331
331
|
// 优化按钮生成逻辑,减少重复条件判断
|
|
332
|
-
if (!this.
|
|
332
|
+
if (!this.showDefaultButtons) {
|
|
333
333
|
return null;
|
|
334
334
|
}
|
|
335
335
|
let buttons = this.buttons;
|
|
@@ -419,6 +419,10 @@ export default {
|
|
|
419
419
|
const name = node.name || 'div';
|
|
420
420
|
const attrs = node.attrs || {};
|
|
421
421
|
const props = node.props || {};
|
|
422
|
+
// 定义数组形态:仅输出值被改动过的条目
|
|
423
|
+
const propsList = Array.isArray(props)
|
|
424
|
+
? props.filter((p) => p && p.name && p.value !== undefined)
|
|
425
|
+
: null;
|
|
422
426
|
const directives = node.directives || {};
|
|
423
427
|
const events = node.events || {};
|
|
424
428
|
|
|
@@ -429,17 +433,32 @@ export default {
|
|
|
429
433
|
attrStr += ' ' + key + '="' + val + '"';
|
|
430
434
|
}
|
|
431
435
|
});
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
436
|
+
if (propsList) {
|
|
437
|
+
propsList.forEach((item) => {
|
|
438
|
+
const val = item.value;
|
|
439
|
+
if (typeof val === 'string') {
|
|
440
|
+
// {{var}} 整体匹配输出绑定表达式,字面量加引号绑定
|
|
441
|
+
const full = /^\{\{([\s\S]+)\}\}$/.exec(val);
|
|
442
|
+
attrStr += full
|
|
443
|
+
? ' :' + item.name + '="' + full[1].trim() + '"'
|
|
444
|
+
: ' :' + item.name + "='" + val + "'";
|
|
438
445
|
} else {
|
|
439
|
-
attrStr += ' :' +
|
|
446
|
+
attrStr += ' :' + item.name + '="' + val + '"';
|
|
440
447
|
}
|
|
441
|
-
}
|
|
442
|
-
}
|
|
448
|
+
});
|
|
449
|
+
} else {
|
|
450
|
+
Object.keys(props).forEach((key) => {
|
|
451
|
+
const val = props[key];
|
|
452
|
+
if (val !== undefined && val !== null && val !== '') {
|
|
453
|
+
// 指令已迁移到 directives,这里仅兼容历史数据中混入 props 的 v- 键
|
|
454
|
+
if (key.startsWith('v-')) {
|
|
455
|
+
attrStr += ' ' + key + '="' + val + '"';
|
|
456
|
+
} else {
|
|
457
|
+
attrStr += ' :' + key + '="' + val + '"';
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
});
|
|
461
|
+
}
|
|
443
462
|
Object.keys(directives).forEach((key) => {
|
|
444
463
|
const val = directives[key];
|
|
445
464
|
if (val !== undefined && val !== null && val !== '') {
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="es-lowcode__props">
|
|
3
|
+
<div class="es-lowcode__props--tip">
|
|
4
|
+
字符串取值可用 <code v-text="codeExample"></code> 引用页面 data
|
|
5
|
+
中定义的变量,其余按字面量传入
|
|
6
|
+
</div>
|
|
7
|
+
<es-form
|
|
8
|
+
label-width="auto"
|
|
9
|
+
size="small"
|
|
10
|
+
:model="models"
|
|
11
|
+
:contents="formContents"
|
|
12
|
+
:show-buttons="false"
|
|
13
|
+
@change="handleChange"
|
|
14
|
+
></es-form>
|
|
15
|
+
</div>
|
|
16
|
+
</template>
|
|
17
|
+
|
|
18
|
+
<script>
|
|
19
|
+
import EsForm from 'eoss/packages/form';
|
|
20
|
+
import { genNode } from '../util/source-generator';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* 组件 props 面板:props 定义数据存在节点自身 props 字段
|
|
24
|
+
* (定义数组,拖入画布时从组件库清单拷贝),格式
|
|
25
|
+
* [{ name, type, default?, options?, value? }],value 仅改动后写入;
|
|
26
|
+
* type 支持 text / number / switch / select;面板按选中节点的定义
|
|
27
|
+
* 渲染取值字段,字符串取值支持 {{变量名}} 引用页面 data 变量
|
|
28
|
+
*/
|
|
29
|
+
export default {
|
|
30
|
+
name: 'PropsPanel',
|
|
31
|
+
inject: ['lowcode'],
|
|
32
|
+
|
|
33
|
+
components: { EsForm },
|
|
34
|
+
|
|
35
|
+
props: {
|
|
36
|
+
model: {
|
|
37
|
+
type: Object,
|
|
38
|
+
default: () => ({})
|
|
39
|
+
},
|
|
40
|
+
contents: {
|
|
41
|
+
type: Array,
|
|
42
|
+
default: () => []
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
|
|
46
|
+
data() {
|
|
47
|
+
return {
|
|
48
|
+
models: {},
|
|
49
|
+
// 面板说明文案中的示例,避免 Vue 把 {{}} 当成插值
|
|
50
|
+
codeExample: '{{变量名}}'
|
|
51
|
+
};
|
|
52
|
+
},
|
|
53
|
+
|
|
54
|
+
watch: {
|
|
55
|
+
// 切换选中组件时回显取值(仅引用变化同步,编辑由 @change 驱动);
|
|
56
|
+
// 按注册表定义遍历,从 model.props 读取当前值(兼容数组/对象两种形态)
|
|
57
|
+
model: {
|
|
58
|
+
handler() {
|
|
59
|
+
const models = {};
|
|
60
|
+
this.formContents.forEach((def) => {
|
|
61
|
+
models[def.name] = this.getPropValue(def.name, def);
|
|
62
|
+
});
|
|
63
|
+
this.models = models;
|
|
64
|
+
},
|
|
65
|
+
immediate: true
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
computed: {
|
|
70
|
+
/**
|
|
71
|
+
* 选中节点自带的 props 定义数组
|
|
72
|
+
*/
|
|
73
|
+
schema() {
|
|
74
|
+
const props = this.model && this.model.props;
|
|
75
|
+
return Array.isArray(props) ? props : [];
|
|
76
|
+
},
|
|
77
|
+
/**
|
|
78
|
+
* 取值表单字段:按定义项渲染
|
|
79
|
+
*/
|
|
80
|
+
formContents() {
|
|
81
|
+
// 从组件库中找到当前选中组件的定义(优先 components,其次 library)
|
|
82
|
+
const components = this.lowcode.components || [];
|
|
83
|
+
const library = this.lowcode.library || [];
|
|
84
|
+
let componentDef = null;
|
|
85
|
+
|
|
86
|
+
// 先在 components 中查找
|
|
87
|
+
componentDef = components.find((c) => c.name === this.model.name);
|
|
88
|
+
|
|
89
|
+
// 没找到则在 library 分组中查找(tab → group/component)
|
|
90
|
+
if (!componentDef) {
|
|
91
|
+
for (const tab of library) {
|
|
92
|
+
for (const item of tab.children || []) {
|
|
93
|
+
// item 可能是分组(有 children)或直接是组件(无 children)
|
|
94
|
+
if (item.children && Array.isArray(item.children)) {
|
|
95
|
+
// 分组:在 children 中找组件
|
|
96
|
+
const found = item.children.find(
|
|
97
|
+
(c) => c.name === this.model.name
|
|
98
|
+
);
|
|
99
|
+
if (found) {
|
|
100
|
+
componentDef = found;
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
} else if (item.name === this.model.name) {
|
|
104
|
+
// 直接是组件
|
|
105
|
+
componentDef = item;
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
if (componentDef) break;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (!componentDef) return [];
|
|
114
|
+
const props = (componentDef.props || []).map((item) => {
|
|
115
|
+
if (item.type === 'text') {
|
|
116
|
+
return {
|
|
117
|
+
...item,
|
|
118
|
+
append: {
|
|
119
|
+
icon: 'es-icon-xiugai',
|
|
120
|
+
event: (e) => this.handleEdit(item)
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
return item;
|
|
125
|
+
});
|
|
126
|
+
// 返回该组件的 props 定义数组
|
|
127
|
+
return props;
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
|
|
131
|
+
methods: {
|
|
132
|
+
handleChange() {
|
|
133
|
+
// 定义数组原样回写,取值与默认值不同的条目才写入 value(进 JSON)
|
|
134
|
+
const props = this.schema.map((item) => {
|
|
135
|
+
const next = { ...item };
|
|
136
|
+
const val = this.models[item.name];
|
|
137
|
+
if (val !== undefined && val !== item.default) {
|
|
138
|
+
next.value = val;
|
|
139
|
+
} else {
|
|
140
|
+
delete next.value;
|
|
141
|
+
}
|
|
142
|
+
return next;
|
|
143
|
+
});
|
|
144
|
+
this.$emit('change', { props });
|
|
145
|
+
},
|
|
146
|
+
/**
|
|
147
|
+
* 打开源码编辑器,光标定位到对应 prop
|
|
148
|
+
* 参考 bind.vue:构建完整 Vue 源码,保存时由 parseVueSource 解析回写
|
|
149
|
+
*/
|
|
150
|
+
handleEdit(item) {
|
|
151
|
+
if (!item) return;
|
|
152
|
+
const source = this.buildFullVueSource();
|
|
153
|
+
this.$emit(
|
|
154
|
+
'edit',
|
|
155
|
+
{
|
|
156
|
+
name: 'props',
|
|
157
|
+
label: '编辑 ' + item.name,
|
|
158
|
+
cursorField: item.name
|
|
159
|
+
},
|
|
160
|
+
source
|
|
161
|
+
);
|
|
162
|
+
},
|
|
163
|
+
/**
|
|
164
|
+
* 构建完整的 Vue 组件源码(参考 bind.vue)
|
|
165
|
+
* 模板中保留根元素的 props/attrs/指令/事件,保存时解析回写
|
|
166
|
+
*/
|
|
167
|
+
buildFullVueSource() {
|
|
168
|
+
const m = this.model;
|
|
169
|
+
const tagName = m.type === 'page' ? 'div' : m.name || 'div';
|
|
170
|
+
const rootNode = Object.assign({}, m, { name: tagName });
|
|
171
|
+
rootNode.children = Array.isArray(m.children) ? m.children : [];
|
|
172
|
+
const templateContent = genNode(rootNode, 1);
|
|
173
|
+
const template = '<template>\n' + templateContent + '\n</template>';
|
|
174
|
+
|
|
175
|
+
const scriptParts = [];
|
|
176
|
+
if (m.data && Object.keys(m.data).length > 0) {
|
|
177
|
+
scriptParts.push(
|
|
178
|
+
' data() {\n return ' + JSON.stringify(m.data, null, 2) + ';\n }'
|
|
179
|
+
);
|
|
180
|
+
} else {
|
|
181
|
+
scriptParts.push(' data() {\n return {};\n }');
|
|
182
|
+
}
|
|
183
|
+
if (m.computed && Object.keys(m.computed).length > 0) {
|
|
184
|
+
scriptParts.push(' computed: ' + JSON.stringify(m.computed, null, 2));
|
|
185
|
+
} else {
|
|
186
|
+
scriptParts.push(' computed: {}');
|
|
187
|
+
}
|
|
188
|
+
if (m.methods && Object.keys(m.methods).length > 0) {
|
|
189
|
+
scriptParts.push(' methods: ' + JSON.stringify(m.methods, null, 2));
|
|
190
|
+
} else {
|
|
191
|
+
scriptParts.push(' methods: {}');
|
|
192
|
+
}
|
|
193
|
+
const script =
|
|
194
|
+
'<script>\nexport default {\n' +
|
|
195
|
+
scriptParts.join(',\n\n') +
|
|
196
|
+
'\n}\n<\/script>';
|
|
197
|
+
const style = '<style lang="scss" scoped>\n\n</style>';
|
|
198
|
+
return template + '\n\n' + script + '\n\n' + style;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
</script>
|
|
@@ -5,9 +5,10 @@
|
|
|
5
5
|
label-width="auto"
|
|
6
6
|
size="small"
|
|
7
7
|
:model="models"
|
|
8
|
-
:contents="
|
|
8
|
+
:contents="formContents"
|
|
9
9
|
:hides="formHides"
|
|
10
10
|
:show-buttons="false"
|
|
11
|
+
@input="handleInput"
|
|
11
12
|
@change="handleChange"
|
|
12
13
|
>
|
|
13
14
|
</es-form>
|
|
@@ -16,6 +17,7 @@
|
|
|
16
17
|
|
|
17
18
|
<script>
|
|
18
19
|
import EsForm from 'eoss/packages/form';
|
|
20
|
+
import { getPropRaw } from '../util/props-util.js';
|
|
19
21
|
export default {
|
|
20
22
|
name: 'Styles',
|
|
21
23
|
inject: ['lowcode'],
|
|
@@ -29,6 +31,39 @@ export default {
|
|
|
29
31
|
}
|
|
30
32
|
},
|
|
31
33
|
|
|
34
|
+
computed: {
|
|
35
|
+
/**
|
|
36
|
+
* 当前选中节点是否为 es-form:列数字段绑组件 props.columns 而非 style
|
|
37
|
+
*/
|
|
38
|
+
isFormModel() {
|
|
39
|
+
const name = (this.model && this.model.name) || '';
|
|
40
|
+
// 节点名是 PascalCase (EsForm),转小写后是 esform
|
|
41
|
+
return name.toLowerCase() === 'esform';
|
|
42
|
+
},
|
|
43
|
+
/**
|
|
44
|
+
* 瀑布流仅页面根节点支持:非页面节点过滤掉 masonry 选项
|
|
45
|
+
*/
|
|
46
|
+
formContents() {
|
|
47
|
+
let list = this.contents;
|
|
48
|
+
if (!this.model || this.model.type !== 'page') {
|
|
49
|
+
list = list.map((item) => {
|
|
50
|
+
if (item.name !== 'display') return item;
|
|
51
|
+
return {
|
|
52
|
+
...item,
|
|
53
|
+
data: item.data.filter((opt) => opt.value !== 'masonry')
|
|
54
|
+
};
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
if (this.isFormModel) {
|
|
58
|
+
// 表单列数复用 columns 字段(写 props.columns),标签改为“列数”
|
|
59
|
+
list = list.map((item) =>
|
|
60
|
+
item.name === 'columns' ? { ...item, label: '列数' } : item
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
return list;
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
|
|
32
67
|
data() {
|
|
33
68
|
return {
|
|
34
69
|
contents: [
|
|
@@ -62,7 +97,6 @@ export default {
|
|
|
62
97
|
label: '总列数',
|
|
63
98
|
min: 1,
|
|
64
99
|
max: 12,
|
|
65
|
-
default: false,
|
|
66
100
|
type: 'number'
|
|
67
101
|
},
|
|
68
102
|
{
|
|
@@ -293,8 +327,6 @@ export default {
|
|
|
293
327
|
};
|
|
294
328
|
},
|
|
295
329
|
|
|
296
|
-
computed: {},
|
|
297
|
-
|
|
298
330
|
watch: {
|
|
299
331
|
/**
|
|
300
332
|
* 监听 model prop 变化(仅用于切换组件时的初始化同步)
|
|
@@ -318,7 +350,13 @@ export default {
|
|
|
318
350
|
this.$set(target, 'style', style);
|
|
319
351
|
}
|
|
320
352
|
}
|
|
321
|
-
|
|
353
|
+
// 表单列数回显 props.columns(定义数组取条目 value/default),缺省 1 列
|
|
354
|
+
const columnsRaw = this.isFormModel
|
|
355
|
+
? getPropRaw(val.props, 'columns')
|
|
356
|
+
: undefined;
|
|
357
|
+
this.models = this.isFormModel
|
|
358
|
+
? { ...style, columns: columnsRaw || 1 }
|
|
359
|
+
: style;
|
|
322
360
|
// 根据 display 类型更新 formHides
|
|
323
361
|
this.updateFormHides(style.display);
|
|
324
362
|
// flex 模式下移除 style 中的 span
|
|
@@ -379,6 +417,14 @@ export default {
|
|
|
379
417
|
);
|
|
380
418
|
}
|
|
381
419
|
|
|
420
|
+
if (this.isFormModel) {
|
|
421
|
+
// 表单节点:columns 绑 props.columns(表单列数)始终可见;
|
|
422
|
+
// span 是页面 grid 占列属性,对表单隐藏避免与“列数”混淆
|
|
423
|
+
const colIdx = hides.indexOf('columns');
|
|
424
|
+
if (colIdx !== -1) hides.splice(colIdx, 1);
|
|
425
|
+
if (!hides.includes('span')) hides.push('span');
|
|
426
|
+
}
|
|
427
|
+
|
|
382
428
|
this.formHides = hides;
|
|
383
429
|
},
|
|
384
430
|
/**
|
|
@@ -416,7 +462,35 @@ export default {
|
|
|
416
462
|
this.updateFormHides(val);
|
|
417
463
|
this.removeSpanIfFlex(val);
|
|
418
464
|
},
|
|
465
|
+
/**
|
|
466
|
+
* 监听字段值变化,同步更新 models(v-model 的 input 事件)
|
|
467
|
+
*/
|
|
468
|
+
handleInput(val) {
|
|
469
|
+
this.models = val;
|
|
470
|
+
},
|
|
419
471
|
handleChange() {
|
|
472
|
+
if (this.isFormModel) {
|
|
473
|
+
// 列数写组件 props 的 columns 条目(定义数组写 value),不污染 style.columns 布局键
|
|
474
|
+
const { columns, ...style } = this.models;
|
|
475
|
+
let props;
|
|
476
|
+
if (Array.isArray(this.model.props)) {
|
|
477
|
+
props = this.model.props.map((item) => ({ ...item }));
|
|
478
|
+
const target = props.find((item) => item.name === 'columns');
|
|
479
|
+
if (target) {
|
|
480
|
+
target.value = columns || 1;
|
|
481
|
+
} else {
|
|
482
|
+
props.push({
|
|
483
|
+
name: 'columns',
|
|
484
|
+
type: 'number',
|
|
485
|
+
value: columns || 1
|
|
486
|
+
});
|
|
487
|
+
}
|
|
488
|
+
} else {
|
|
489
|
+
props = { ...(this.model.props || {}), columns: columns || 1 };
|
|
490
|
+
}
|
|
491
|
+
this.$emit('change', { style, props });
|
|
492
|
+
return;
|
|
493
|
+
}
|
|
420
494
|
this.$emit('change', { style: this.models });
|
|
421
495
|
}
|
|
422
496
|
}
|
|
@@ -4,7 +4,14 @@
|
|
|
4
4
|
<es-tab-pane label="样式" name="1" lazy>
|
|
5
5
|
<styles :model="current" @change="handleModelUpdate"></styles>
|
|
6
6
|
</es-tab-pane>
|
|
7
|
-
<es-tab-pane label="
|
|
7
|
+
<es-tab-pane v-if="showPropsTab" label="props" name="6" lazy>
|
|
8
|
+
<props-panel
|
|
9
|
+
:model="current"
|
|
10
|
+
@change="handleModelUpdate"
|
|
11
|
+
@edit="handleEdit"
|
|
12
|
+
></props-panel>
|
|
13
|
+
</es-tab-pane>
|
|
14
|
+
<es-tab-pane v-if="isPageNode" label="定义" name="2" lazy>
|
|
8
15
|
<property
|
|
9
16
|
:model="current"
|
|
10
17
|
@change="handleModelUpdate"
|
|
@@ -18,14 +25,14 @@
|
|
|
18
25
|
@edit="handleEdit"
|
|
19
26
|
></bind>
|
|
20
27
|
</es-tab-pane>
|
|
21
|
-
<es-tab-pane label="函数" name="4" lazy>
|
|
28
|
+
<es-tab-pane v-if="isPageNode" label="函数" name="4" lazy>
|
|
22
29
|
<functions
|
|
23
30
|
:model="current"
|
|
24
31
|
@change="handleModelUpdate"
|
|
25
32
|
@edit="handleEdit"
|
|
26
33
|
></functions>
|
|
27
34
|
</es-tab-pane>
|
|
28
|
-
<es-tab-pane label="依赖" name="5" lazy>
|
|
35
|
+
<es-tab-pane v-if="isPageNode" label="依赖" name="5" lazy>
|
|
29
36
|
<dependency
|
|
30
37
|
:model="current"
|
|
31
38
|
@pageChange="handlePageUpdate"
|
|
@@ -58,6 +65,7 @@ import bus from 'eoss/src/utils/bus.js';
|
|
|
58
65
|
import busListener from './mixins/bus-listener.js';
|
|
59
66
|
import Property from './attribute/property.vue';
|
|
60
67
|
import Styles from './attribute/styles.vue';
|
|
68
|
+
import PropsPanel from './attribute/props.vue';
|
|
61
69
|
import Bind from './attribute/bind.vue';
|
|
62
70
|
import Functions from './attribute/function.vue';
|
|
63
71
|
import Dependency from './attribute/dependency.vue';
|
|
@@ -191,6 +199,7 @@ export default {
|
|
|
191
199
|
components: {
|
|
192
200
|
Property,
|
|
193
201
|
Styles,
|
|
202
|
+
PropsPanel,
|
|
194
203
|
Bind,
|
|
195
204
|
Functions,
|
|
196
205
|
LowJs,
|
|
@@ -229,10 +238,38 @@ export default {
|
|
|
229
238
|
editingField: null
|
|
230
239
|
};
|
|
231
240
|
},
|
|
232
|
-
computed: {
|
|
241
|
+
computed: {
|
|
242
|
+
/**
|
|
243
|
+
* 选中节点是否为页面:定义/函数/依赖仅页面可编辑
|
|
244
|
+
*/
|
|
245
|
+
isPageNode() {
|
|
246
|
+
return !!this.current && this.current.type === 'page';
|
|
247
|
+
},
|
|
248
|
+
/**
|
|
249
|
+
* 选中节点是否为原生 HTML 元素:仅样式 + 绑定(属性/指令/事件)
|
|
250
|
+
*/
|
|
251
|
+
isHtmlNode() {
|
|
252
|
+
return !!this.current && this.isNativeHtmlTag(this.current.name);
|
|
253
|
+
},
|
|
254
|
+
/**
|
|
255
|
+
* 组件节点显示 props 面板:按组件定义的 props 传入数据
|
|
256
|
+
*/
|
|
257
|
+
showPropsTab() {
|
|
258
|
+
return !!this.current && !this.isPageNode && !this.isHtmlNode;
|
|
259
|
+
}
|
|
260
|
+
},
|
|
233
261
|
watch: {
|
|
234
262
|
show(val) {
|
|
235
263
|
this.styles.width = val ? '350px' : '0px';
|
|
264
|
+
},
|
|
265
|
+
// 切换选中节点时,若当前 tab 对新节点类型不可见则回落到样式页
|
|
266
|
+
current() {
|
|
267
|
+
const pageOnly = ['2', '4', '5'];
|
|
268
|
+
if (!this.isPageNode && pageOnly.includes(this.active)) {
|
|
269
|
+
this.active = '1';
|
|
270
|
+
} else if (!this.showPropsTab && this.active === '6') {
|
|
271
|
+
this.active = '1';
|
|
272
|
+
}
|
|
236
273
|
}
|
|
237
274
|
},
|
|
238
275
|
mounted() {
|
|
@@ -885,3 +922,23 @@ export default {
|
|
|
885
922
|
}
|
|
886
923
|
};
|
|
887
924
|
</script>
|
|
925
|
+
|
|
926
|
+
<style lang="scss" scoped>
|
|
927
|
+
.es-lowcode__attribute {
|
|
928
|
+
height: 100%;
|
|
929
|
+
}
|
|
930
|
+
// 面板内容区滚动:tab 头固定,内容超出时纵向滚动
|
|
931
|
+
.es-lowcode__attribute--tabs {
|
|
932
|
+
height: 100%;
|
|
933
|
+
display: flex;
|
|
934
|
+
flex-direction: column;
|
|
935
|
+
|
|
936
|
+
::v-deep .es-tabs__header {
|
|
937
|
+
flex-shrink: 0;
|
|
938
|
+
}
|
|
939
|
+
::v-deep .es-tabs__content {
|
|
940
|
+
flex: 1;
|
|
941
|
+
overflow-y: auto;
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
</style>
|