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.
Files changed (233) hide show
  1. package/lib/0.js +1 -1
  2. package/lib/1.js +1 -1
  3. package/lib/10.js +1 -1
  4. package/lib/11.js +1 -1
  5. package/lib/12.js +1 -1
  6. package/lib/13.js +1 -1
  7. package/lib/14.js +1 -1
  8. package/lib/15.js +1 -1
  9. package/lib/16.js +1 -1
  10. package/lib/17.js +1 -1
  11. package/lib/18.js +1 -1
  12. package/lib/19.js +1 -1
  13. package/lib/20.js +1 -1
  14. package/lib/21.js +1 -1
  15. package/lib/22.js +1 -1
  16. package/lib/23.js +1 -1
  17. package/lib/24.js +1 -1
  18. package/lib/25.js +1 -1
  19. package/lib/26.js +1 -1
  20. package/lib/27.js +1 -1
  21. package/lib/28.js +1 -1
  22. package/lib/29.js +1 -1
  23. package/lib/3.js +1 -1
  24. package/lib/30.js +1 -1
  25. package/lib/31.js +1 -1
  26. package/lib/32.js +1 -1
  27. package/lib/33.js +1 -1
  28. package/lib/34.js +1 -1
  29. package/lib/35.js +1 -1
  30. package/lib/36.js +1 -1
  31. package/lib/37.js +1 -1
  32. package/lib/38.js +1 -1
  33. package/lib/39.js +1 -1
  34. package/lib/4.js +1 -1
  35. package/lib/40.js +1 -1
  36. package/lib/41.js +1 -1
  37. package/lib/42.js +1 -1
  38. package/lib/43.js +1 -1
  39. package/lib/44.js +1 -1
  40. package/lib/45.js +1 -1
  41. package/lib/46.js +1 -1
  42. package/lib/47.js +1 -1
  43. package/lib/48.js +1 -1
  44. package/lib/49.js +1 -1
  45. package/lib/5.js +1 -1
  46. package/lib/50.js +1 -1
  47. package/lib/51.js +1 -1
  48. package/lib/52.js +1 -1
  49. package/lib/53.js +1 -1
  50. package/lib/54.js +1 -1
  51. package/lib/55.js +1 -1
  52. package/lib/56.js +1 -1
  53. package/lib/57.js +1 -1
  54. package/lib/58.js +1 -1
  55. package/lib/59.js +1 -1
  56. package/lib/6.js +1 -1
  57. package/lib/60.js +1 -1
  58. package/lib/61.js +1 -1
  59. package/lib/62.js +1 -1
  60. package/lib/63.js +1 -1
  61. package/lib/64.js +1 -1
  62. package/lib/65.js +1 -1
  63. package/lib/66.js +1 -1
  64. package/lib/67.js +1 -1
  65. package/lib/68.js +1 -1
  66. package/lib/69.js +1 -1
  67. package/lib/7.js +1 -1
  68. package/lib/70.js +1 -1
  69. package/lib/71.js +1 -1
  70. package/lib/72.js +1 -1
  71. package/lib/73.js +1 -1
  72. package/lib/74.js +1 -1
  73. package/lib/75.js +1 -1
  74. package/lib/76.js +1 -1
  75. package/lib/77.js +1 -1
  76. package/lib/78.js +1 -1
  77. package/lib/79.js +1 -1
  78. package/lib/8.js +1 -1
  79. package/lib/80.js +1 -1
  80. package/lib/81.js +1 -1
  81. package/lib/9.js +1 -1
  82. package/lib/account-login.js +837 -862
  83. package/lib/alert.js +2 -2
  84. package/lib/aside.js +2 -2
  85. package/lib/audit-trajectory.js +4 -4
  86. package/lib/autocomplete.js +1813 -1988
  87. package/lib/avatar.js +2 -2
  88. package/lib/backtop.js +2 -2
  89. package/lib/badge.js +2 -2
  90. package/lib/breadcrumb-item.js +4 -4
  91. package/lib/breadcrumb.js +4 -4
  92. package/lib/button-group.js +4 -4
  93. package/lib/button.js +2 -2
  94. package/lib/ca-login.js +837 -862
  95. package/lib/calendar.js +839 -864
  96. package/lib/card.js +2 -2
  97. package/lib/carousel-item.js +846 -871
  98. package/lib/carousel.js +839 -864
  99. package/lib/cascader-panel.js +852 -877
  100. package/lib/cascader.js +2048 -2223
  101. package/lib/checkbox-button.js +4 -4
  102. package/lib/checkbox-group.js +859 -884
  103. package/lib/checkbox.js +4 -4
  104. package/lib/col.js +2 -2
  105. package/lib/collapse-item.js +1040 -1065
  106. package/lib/collapse.js +1040 -1065
  107. package/lib/color-picker.js +972 -1122
  108. package/lib/container.js +2 -2
  109. package/lib/cron.js +12 -12
  110. package/lib/data-table.js +843 -868
  111. package/lib/date-picker.js +10520 -10695
  112. package/lib/descriptions-item.js +4 -4
  113. package/lib/descriptions.js +4 -4
  114. package/lib/dialog.js +837 -862
  115. package/lib/divider.js +2 -2
  116. package/lib/drawer.js +2 -2
  117. package/lib/dropdown-item.js +4 -4
  118. package/lib/dropdown-menu.js +974 -1124
  119. package/lib/dropdown.js +841 -866
  120. package/lib/email-login.js +837 -862
  121. package/lib/empty.js +2 -2
  122. package/lib/eoss.common.js +4023 -2668
  123. package/lib/flip.js +2 -2
  124. package/lib/flow-group.js +853 -878
  125. package/lib/flow.js +868 -893
  126. package/lib/flows.js +854 -879
  127. package/lib/footer.js +2 -2
  128. package/lib/form-item.js +860 -885
  129. package/lib/form.js +933 -950
  130. package/lib/guide.js +2 -2
  131. package/lib/header.js +2 -2
  132. package/lib/icon.js +837 -862
  133. package/lib/icons.js +2 -2
  134. package/lib/image-viewer.js +837 -862
  135. package/lib/image.js +4 -4
  136. package/lib/index.js +1 -1
  137. package/lib/infinite-scroll.js +2 -2
  138. package/lib/input-number.js +6 -6
  139. package/lib/input.js +839 -864
  140. package/lib/link.js +2 -2
  141. package/lib/loading.js +2 -2
  142. package/lib/login.js +867 -891
  143. package/lib/lowcode-view.js +1843 -1185
  144. package/lib/lowcode.js +3050 -1569
  145. package/lib/main.js +970 -988
  146. package/lib/marquee.js +837 -862
  147. package/lib/menu-item-group.js +15 -15
  148. package/lib/menu-item.js +6 -6
  149. package/lib/menu.js +2227 -2368
  150. package/lib/message-box.js +843 -868
  151. package/lib/message.js +839 -864
  152. package/lib/notification.js +861 -886
  153. package/lib/option-group.js +4 -4
  154. package/lib/option.js +839 -864
  155. package/lib/page-header.js +2 -2
  156. package/lib/pagination.js +839 -864
  157. package/lib/phone-login.js +847 -866
  158. package/lib/popconfirm.js +4 -4
  159. package/lib/popover.js +1831 -2006
  160. package/lib/process-config.js +839 -864
  161. package/lib/process-module.js +846 -871
  162. package/lib/process-rule.js +905 -930
  163. package/lib/progress.js +2 -2
  164. package/lib/qr-code.js +4 -4
  165. package/lib/qrcode-login.js +839 -864
  166. package/lib/radio-button.js +4 -4
  167. package/lib/radio-group.js +850 -875
  168. package/lib/radio.js +4 -4
  169. package/lib/rate.js +837 -862
  170. package/lib/retrial-auth.js +837 -862
  171. package/lib/row.js +2 -2
  172. package/lib/scrollbar.js +839 -864
  173. package/lib/select.js +2139 -2314
  174. package/lib/selector-panel.js +940 -965
  175. package/lib/selector.js +852 -877
  176. package/lib/slider.js +4 -4
  177. package/lib/step.js +32 -32
  178. package/lib/steps.js +874 -899
  179. package/lib/submenu.js +1269 -1385
  180. package/lib/switch.js +839 -864
  181. package/lib/tab-pane.js +4 -4
  182. package/lib/table-column.js +840 -865
  183. package/lib/table.js +1825 -2000
  184. package/lib/tabs.js +846 -871
  185. package/lib/tag.js +2 -2
  186. package/lib/theme-chalk/fonts/iconfont.ttf +0 -0
  187. package/lib/theme-chalk/fonts/iconfont.woff +0 -0
  188. package/lib/theme-chalk/index.css +1 -1
  189. package/lib/theme-chalk/lowcode.css +1 -1
  190. package/lib/time-picker.js +6471 -6646
  191. package/lib/time-select.js +5039 -5214
  192. package/lib/timeline-item.js +2 -2
  193. package/lib/timeline.js +2 -2
  194. package/lib/tips.js +837 -862
  195. package/lib/toolbar.js +4 -4
  196. package/lib/tooltip.js +1813 -1988
  197. package/lib/transfer.js +837 -862
  198. package/lib/tree-group.js +853 -878
  199. package/lib/tree.js +1026 -1051
  200. package/lib/update-history.js +4 -4
  201. package/lib/upload.js +859 -884
  202. package/lib/wujie.js +841 -866
  203. package/package.json +1 -1
  204. package/packages/flow-group/src/main.vue +2 -2
  205. package/packages/form/src/form-item-render.vue +1 -0
  206. package/packages/form/src/form-item.vue +12 -6
  207. package/packages/form/src/form.vue +5 -5
  208. package/packages/login/src/login.vue +1 -0
  209. package/packages/lowcode/src/attribute/function.vue +28 -9
  210. package/packages/lowcode/src/attribute/props.vue +202 -0
  211. package/packages/lowcode/src/attribute/styles.vue +79 -5
  212. package/packages/lowcode/src/attribute.vue +61 -4
  213. package/packages/lowcode/src/canvas.vue +159 -2
  214. package/packages/lowcode/src/form-render.vue +305 -0
  215. package/packages/lowcode/src/lowcode.vue +33 -13
  216. package/packages/lowcode/src/modules.vue +53 -37
  217. package/packages/lowcode/src/render.vue +80 -25
  218. package/packages/lowcode/src/util/components.js +100 -0
  219. package/packages/lowcode/src/util/props-util.js +67 -0
  220. package/packages/lowcode/src/util/source-generator.js +69 -9
  221. package/packages/lowcode/src/util/source-parser.js +64 -10
  222. package/packages/lowcode-view/src/render.vue +48 -18
  223. package/packages/main/src/components/userinfo.vue +0 -1
  224. package/packages/menu/src/menu-item-group.vue +1 -1
  225. package/packages/menu/src/mixins.js +8 -4
  226. package/packages/menu/src/submenu.vue +35 -5
  227. package/packages/phone-login/src/phone-login.vue +5 -2
  228. package/packages/theme-chalk/dist/fonts/iconfont.ttf +0 -0
  229. package/packages/theme-chalk/dist/fonts/iconfont.woff +0 -0
  230. package/packages/theme-chalk/src/fonts/iconfont.ttf +0 -0
  231. package/packages/theme-chalk/src/fonts/iconfont.woff +0 -0
  232. package/packages/theme-chalk/src/lowcode.scss +21 -2
  233. package/src/index.js +336 -336
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eoss",
3
- "version": "0.1.0-alpha.39",
3
+ "version": "0.1.0-alpha.40",
4
4
  "description": "eoss内部业务组件",
5
5
  "main": "lib/eoss.common.js",
6
6
  "files": [
@@ -160,7 +160,7 @@
160
160
  full
161
161
  :key="index"
162
162
  :autoId="true"
163
- :show-button="false"
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-button="false"
311
+ :show-default-buttons="false"
312
312
  ref="esFlowForm"
313
313
  :showMsg="showMsg"
314
314
  v-bind="
@@ -332,6 +332,7 @@ export default {
332
332
  inline,
333
333
  plain,
334
334
  span,
335
+ default: _default, // 排除定义对象的 default 字段(避免与组件 prop 冲突)
335
336
  ...config
336
337
  } = fieldItem;
337
338
  return {
@@ -4,7 +4,7 @@
4
4
  :style="itemStyle"
5
5
  :class="[
6
6
  {
7
- 'es-form-item--feedback': esForm && esForm.statusIcon,
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 col = this.esForm.col;
254
- if (col > 1) {
253
+ const columns = this.esForm.columns;
254
+ if (columns > 1) {
255
255
  return {
256
- width: `${100 / col}%`
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 (!label || this.labelPosition === 'top' || form.labelPosition === 'top' || form.inline) return {};
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
- col: {
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
- showButton: {
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.showButton) {
332
+ if (!this.showDefaultButtons) {
333
333
  return null;
334
334
  }
335
335
  let buttons = this.buttons;
@@ -639,6 +639,7 @@ export default {
639
639
  operationCheckCode: '',
640
640
  // 用户名
641
641
  userName: '',
642
+ loginModel: '0',
642
643
  // 二次效验接口地址
643
644
  doAssistanceQrLogin: doAssistanceQrLogin,
644
645
  // 二次效验弹窗是否显示
@@ -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
- Object.keys(props).forEach((key) => {
433
- const val = props[key];
434
- if (val !== undefined && val !== null && val !== '') {
435
- // 指令已迁移到 directives,这里仅兼容历史数据中混入 props 的 v- 键
436
- if (key.startsWith('v-')) {
437
- attrStr += ' ' + key + '="' + val + '"';
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 += ' :' + key + '="' + val + '"';
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="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
- this.models = style;
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="定义" name="2" lazy>
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>