@longhongguo/form-create-ant-design-vue 3.3.38 → 3.3.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@longhongguo/form-create-ant-design-vue",
3
- "version": "3.3.38",
3
+ "version": "3.3.40",
4
4
  "description": "AntDesignVue版本低代码表单|FormCreate 是一个可以通过 JSON 生成具有动态渲染、数据收集、验证和提交功能的低代码表单生成组件。支持6个UI框架,适配移动端,并且支持生成任何 Vue 组件。内置20种常用表单组件和自定义组件,再复杂的表单都可以轻松搞定。",
5
5
  "main": "./dist/form-create.min.js",
6
6
  "module": "./dist/form-create.esm.js",
@@ -1,5 +1,8 @@
1
1
  <template>
2
- <div class="fc-editor-wrapper">
2
+ <div
3
+ class="fc-editor-wrapper"
4
+ :class="{ 'fc-editor-preview': isPreviewOrReadOnly }"
5
+ >
3
6
  <!-- 只读/预览模式:直接用 v-html 渲染,并添加图片点击监听 -->
4
7
  <div
5
8
  v-if="readOnly"
@@ -8,14 +11,14 @@
8
11
  v-html="modelValue"
9
12
  ></div>
10
13
  <!-- 编辑模式:使用富文本编辑器 -->
11
- <FcEditor
14
+ <FcEditor
12
15
  v-else
13
- :model-value="modelValue"
14
- :disabled="disabled"
15
- :config="editorConfig"
16
- :init="initEditor"
17
- @update:model-value="$emit('update:modelValue', $event)"
18
- />
16
+ :model-value="modelValue"
17
+ :disabled="disabled"
18
+ :config="editorConfig"
19
+ :init="initEditor"
20
+ @update:model-value="$emit('update:modelValue', $event)"
21
+ />
19
22
  </div>
20
23
  </template>
21
24
 
@@ -87,6 +90,9 @@ export default defineComponent({
87
90
  }
88
91
  },
89
92
  computed: {
93
+ isPreviewOrReadOnly() {
94
+ return this.readOnly || this.formCreateInject?.preview === true
95
+ },
90
96
  editorConfig() {
91
97
  const config = {}
92
98
 
@@ -1234,6 +1240,10 @@ export default defineComponent({
1234
1240
  width: 100%;
1235
1241
  }
1236
1242
 
1243
+ .fc-editor-wrapper.fc-editor-preview {
1244
+ height: auto !important;
1245
+ }
1246
+
1237
1247
  .fc-editor-readonly {
1238
1248
  padding: 0 10px;
1239
1249
  border-radius: 4px;
@@ -88,6 +88,16 @@ export default {
88
88
  }
89
89
  },
90
90
  watch: {
91
+ columns: {
92
+ handler() {
93
+ // 当 columns 变化时,重新解析 optionsFn
94
+ this.parseColumnsOptionsFn()
95
+ this.loadRule()
96
+ this.updateTable()
97
+ },
98
+ deep: true,
99
+ immediate: false
100
+ },
91
101
  modelValue: {
92
102
  handler() {
93
103
  this.updateTable()
@@ -125,6 +135,7 @@ export default {
125
135
  copyTrs: '',
126
136
  oldValue: '',
127
137
  selectedRows: new Set(), // 存储选中行的索引
138
+ parsedColumns: [], // 存储解析后的 columns(包含解析后的 optionsFn)
128
139
  emptyRule: {
129
140
  type: 'tr',
130
141
  _isEmpty: true,
@@ -152,9 +163,56 @@ export default {
152
163
  }
153
164
  },
154
165
  methods: {
166
+ parseColumnsOptionsFn() {
167
+ // 使用 formCreate 的 parseFn 来解析 optionsFn 字符串为函数
168
+ let parseFn
169
+ if (this.formCreateInject?.form?.parseFn) {
170
+ parseFn = this.formCreateInject.form.parseFn
171
+ } else {
172
+ // 如果 formCreateInject 中没有 parseFn,尝试动态 require
173
+ try {
174
+ const jsonUtils = require('@form-create/utils/lib/json')
175
+ parseFn = jsonUtils.parseFn
176
+ } catch (e) {
177
+ // 如果 require 失败,创建一个简单的解析函数
178
+ parseFn = (fn) => {
179
+ if (typeof fn !== 'string') return fn
180
+ // 尝试解析 [[FORM-CREATE-PREFIX-...-FORM-CREATE-SUFFIX]] 格式
181
+ const PREFIX = '[[FORM-CREATE-PREFIX-'
182
+ const SUFFIX = '-FORM-CREATE-SUFFIX]]'
183
+ if (fn.indexOf(PREFIX) === 0 && fn.indexOf(SUFFIX) > 0) {
184
+ const funcStr = fn.replace(SUFFIX, '').replace(PREFIX, '')
185
+ try {
186
+ return new Function('return ' + funcStr)()
187
+ } catch (err) {
188
+ console.warn('Failed to parse optionsFn:', err)
189
+ return fn
190
+ }
191
+ }
192
+ return fn
193
+ }
194
+ }
195
+ }
196
+
197
+ this.parsedColumns = (this.columns || []).map((column) => {
198
+ const parsedColumn = { ...column }
199
+ // 如果 optionsFn 是字符串,解析为函数
200
+ if (column.optionsFn) {
201
+ if (typeof column.optionsFn === 'string') {
202
+ parsedColumn.optionsFn = parseFn(column.optionsFn)
203
+ } else if (typeof column.optionsFn === 'function') {
204
+ // 如果已经是函数,直接使用
205
+ parsedColumn.optionsFn = column.optionsFn
206
+ }
207
+ }
208
+ return parsedColumn
209
+ })
210
+ },
155
211
  getEmptyColspan() {
212
+ const columnsToUse =
213
+ this.parsedColumns.length > 0 ? this.parsedColumns : this.columns
156
214
  return (
157
- this.columns.length +
215
+ columnsToUse.length +
158
216
  (this.showIndexColumn ? 1 : 0) +
159
217
  (this.showSelectColumn ? 1 : 0) +
160
218
  (this.showOperationColumn ? (this.formCreateInject.preview ? 0 : 1) : 0)
@@ -201,7 +259,7 @@ export default {
201
259
  return
202
260
  }
203
261
  this.oldValue = str
204
-
262
+
205
263
  // 从数据中读取选中状态,初始化 selectedRows
206
264
  if (this.showSelectColumn) {
207
265
  this.selectedRows.clear()
@@ -211,7 +269,7 @@ export default {
211
269
  }
212
270
  })
213
271
  }
214
-
272
+
215
273
  this.trs = this.trs.splice(0, this.modelValue.length)
216
274
  if (!this.modelValue.length) {
217
275
  this.addEmpty()
@@ -276,7 +334,7 @@ export default {
276
334
  // 更新 selectedRows,删除当前索引,后续索引前移
277
335
  this.selectedRows.delete(idx)
278
336
  const newSelectedRows = new Set()
279
- this.selectedRows.forEach(selectedIdx => {
337
+ this.selectedRows.forEach((selectedIdx) => {
280
338
  if (selectedIdx < idx) {
281
339
  newSelectedRows.add(selectedIdx)
282
340
  } else if (selectedIdx > idx) {
@@ -284,7 +342,7 @@ export default {
284
342
  }
285
343
  })
286
344
  this.selectedRows = newSelectedRows
287
-
345
+
288
346
  this.updateValue()
289
347
  if (this.trs.length) {
290
348
  this.trs.forEach((tr) => this.updateRaw(tr))
@@ -314,19 +372,19 @@ export default {
314
372
  },
315
373
  updateRaw(tr) {
316
374
  const idx = this.trs.indexOf(tr)
375
+ const rowData = this.modelValue[idx] || {}
317
376
  let colOffset = 0
318
-
377
+
319
378
  // 更新序号列
320
379
  if (this.showIndexColumn && tr.children[colOffset]) {
321
380
  tr.children[colOffset].props.innerText = idx + 1
322
381
  colOffset++
323
382
  }
324
-
383
+
325
384
  // 更新选择列
326
385
  if (this.showSelectColumn && tr.children[colOffset]) {
327
386
  const selectCell = tr.children[colOffset]
328
387
  // 从数据对象中读取选中状态
329
- const rowData = this.modelValue[idx]
330
388
  const isSelected = rowData && rowData[this.selectField] === true
331
389
  if (selectCell.children && selectCell.children[0]) {
332
390
  const checkbox = selectCell.children[0]
@@ -342,7 +400,9 @@ export default {
342
400
  if (tableEl) {
343
401
  const rows = tableEl.querySelectorAll('tbody tr')
344
402
  if (rows[idx]) {
345
- const checkbox = rows[idx].querySelector('._fc-tf-select input[type="checkbox"]')
403
+ const checkbox = rows[idx].querySelector(
404
+ '._fc-tf-select input[type="checkbox"]'
405
+ )
346
406
  if (checkbox) {
347
407
  checkbox.checked = isSelected
348
408
  }
@@ -351,7 +411,38 @@ export default {
351
411
  })
352
412
  colOffset++
353
413
  }
354
-
414
+
415
+ // 更新数据列的动态 options(如 checkbox)
416
+ // 使用 parsedColumns 而不是原始的 columns,确保 optionsFn 已被解析
417
+ const columnsToUse =
418
+ this.parsedColumns.length > 0 ? this.parsedColumns : this.columns
419
+ columnsToUse.forEach((column, colIdx) => {
420
+ const cellIdx = colOffset + colIdx
421
+ if (tr.children[cellIdx] && tr.children[cellIdx].children) {
422
+ const cellChildren = tr.children[cellIdx].children
423
+ // 查找 checkbox 或 radio 类型的规则
424
+ const checkboxRule = cellChildren.find(
425
+ (rule) => rule.type === 'checkbox' || rule.type === 'radio'
426
+ )
427
+ if (
428
+ checkboxRule &&
429
+ column.optionsFn &&
430
+ typeof column.optionsFn === 'function'
431
+ ) {
432
+ // 调用 optionsFn 获取该行的 options
433
+ const dynamicOptions = column.optionsFn(rowData, idx)
434
+ if (Array.isArray(dynamicOptions)) {
435
+ // 更新 checkbox 规则的 options
436
+ checkboxRule.options = dynamicOptions
437
+ // 如果 checkbox 的 props 中有 options,也更新它
438
+ if (checkboxRule.props) {
439
+ checkboxRule.props.options = dynamicOptions
440
+ }
441
+ }
442
+ }
443
+ }
444
+ })
445
+
355
446
  // 更新操作列的删除按钮
356
447
  if (this.showOperationColumn && tr.children[tr.children.length - 1]) {
357
448
  const operationCell = tr.children[tr.children.length - 1]
@@ -407,13 +498,13 @@ export default {
407
498
  },
408
499
  updateSelectAllState() {
409
500
  if (!this.showSelectColumn) return
410
-
501
+
411
502
  const validRows = this.modelValue.filter((rowData, idx) => {
412
503
  const tr = this.trs[idx]
413
504
  return tr && !tr._isEmpty
414
505
  })
415
506
  if (validRows.length === 0) return
416
-
507
+
417
508
  // 从数据对象中读取选中状态
418
509
  const allSelected = validRows.every((rowData) => {
419
510
  return rowData && rowData[this.selectField] === true
@@ -421,12 +512,14 @@ export default {
421
512
  const someSelected = validRows.some((rowData) => {
422
513
  return rowData && rowData[this.selectField] === true
423
514
  })
424
-
515
+
425
516
  // 更新表头的全选checkbox(通过 DOM 操作)
426
517
  this.$nextTick(() => {
427
518
  const tableEl = this.$el?.querySelector('._fc-tf-table')
428
519
  if (tableEl) {
429
- const headerCheckbox = tableEl.querySelector('._fc-tf-head-select input[type="checkbox"]')
520
+ const headerCheckbox = tableEl.querySelector(
521
+ '._fc-tf-head-select input[type="checkbox"]'
522
+ )
430
523
  if (headerCheckbox) {
431
524
  headerCheckbox.checked = allSelected
432
525
  headerCheckbox.indeterminate = !allSelected && someSelected
@@ -520,7 +613,10 @@ export default {
520
613
  }
521
614
 
522
615
  // 数据列
523
- this.columns.forEach((column) => {
616
+ // 使用 parsedColumns 而不是原始的 columns,确保 optionsFn 已被解析
617
+ const columnsToUse =
618
+ this.parsedColumns.length > 0 ? this.parsedColumns : this.columns
619
+ columnsToUse.forEach((column) => {
524
620
  header.push({
525
621
  type: 'th',
526
622
  native: true,
@@ -615,6 +711,8 @@ export default {
615
711
  }
616
712
  },
617
713
  created() {
714
+ // 解析 columns 中的 optionsFn(从字符串解析为函数)
715
+ this.parseColumnsOptionsFn()
618
716
  this.loadRule()
619
717
  },
620
718
  mounted() {
@@ -1,12 +1,12 @@
1
- import {hasProperty} from '@form-create/utils/lib/type';
1
+ import { hasProperty } from '@form-create/utils/lib/type'
2
2
 
3
3
  export default {
4
- name: 'checkbox',
5
- modelField: 'value',
6
- mergeProp(ctx) {
7
- const props = ctx.prop.props;
8
- if (!hasProperty(props, 'options'))
9
- props.options = ctx.prop.options || [];
10
- }
11
-
4
+ name: 'checkbox',
5
+ modelField: 'value',
6
+ mergeProp(ctx) {
7
+ const props = ctx.prop.props
8
+ if (!hasProperty(props, 'options')) props.options = ctx.prop.options || []
9
+ // Ant Design Vue 的 CheckboxGroup 支持在 options 数组中通过 disabled 属性禁用选项
10
+ // 例如: [{ label: '选项1', value: 1, disabled: true }, { label: '选项2', value: 2, disabled: false }]
11
+ }
12
12
  }
@@ -1,5 +1,8 @@
1
1
  import checkbox from './checkbox';
2
2
 
3
3
  export default {
4
- ...checkbox, name: 'radio'
4
+ ...checkbox,
5
+ name: 'radio'
6
+ // Ant Design Vue 的 RadioGroup 同样支持在 options 数组中通过 disabled 属性禁用选项
7
+ // 例如: [{ label: '选项A', value: 'A', disabled: true }, { label: '选项B', value: 'B', disabled: false }]
5
8
  };