@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/dist/form-create.esm.js +2 -2
- package/dist/form-create.esm.js.map +1 -1
- package/dist/form-create.js +2 -2
- package/dist/form-create.js.map +1 -1
- package/package.json +1 -1
- package/src/components/FcEditorWrapper.vue +18 -8
- package/src/components/tableForm/TableForm.vue +113 -15
- package/src/parsers/checkbox.js +9 -9
- package/src/parsers/radio.js +4 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@longhongguo/form-create-ant-design-vue",
|
|
3
|
-
"version": "3.3.
|
|
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
|
|
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
|
-
|
|
14
|
+
<FcEditor
|
|
12
15
|
v-else
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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
|
-
|
|
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(
|
|
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(
|
|
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
|
-
|
|
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() {
|
package/src/parsers/checkbox.js
CHANGED
|
@@ -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
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
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
|
}
|
package/src/parsers/radio.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import checkbox from './checkbox';
|
|
2
2
|
|
|
3
3
|
export default {
|
|
4
|
-
...checkbox,
|
|
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
|
};
|