VForm获取表单控件数据域
1. 介绍
VForm 是一个基于 Vue.js 的表单组件库,它提供了丰富的表单组件,如输入框、选择器、日期选择器等,同时支持表单验证和数据收集等功能。我们往往需要将用户提交的数据已列表的形式展示出来,但是 VForm 并没有提供这样的功能,因此我们需要自己实现一个获取表单控件数据域的方法。
2. 实现思路
要实现获取表单控件数据域的功能,我们需要遍历 VForm 中的表单控件,并将它们的数据存储在一个对象中。具体实现步骤如下:
// 获取所有表单控件,这里需要注意,所有控件都需要静态进入,动态载入的控件这里无法获取到也就无法正常获取到数据域
import { containers, basicFields, advancedFields, customFields } from '@/components/form-designer/widget-panel/widgetsConfig'
// 设置分组,方便后续对容器空间进行处理
const ALL_WIDGET_LIST = [
...containers.map(t => {
t.category = 'container'
return t
}),
...basicFields.map(t => {
t.category = 'basicField'
return t
}),
...advancedFields.map(t => {
t.category = 'advancedField'
return t
}),
...customFields.map(t => {
t.category = 'customField'
return t
})
]
// 获取所有表单控件数据域
export function getFormDataDomain(widgetList, options = {excludes: {category: ['container'], widgets: ['table']}}) {
let formDataDomain = []
for (let i = 0; i < widgetList.length; i++) {
const widget = widgetList[i]
const widgetType = ALL_WIDGET_LIST.find(w => w.type == widget.type)?.category
if (options.excludes !== false) {
if (Array.isArray(options.excludes.category) && options.excludes.category.includes(widgetType)) {
continue
}
if (Array.isArray(options.excludes.widgets) && options.excludes.widgets.includes(widget.type)) {
continue
}
}
if (widgetType == 'container') {
if (widget.type === 'table') {
formDataDomain.push(...getFormDataDomainByTable(widget))
} else if (widget.type === 'grid') {
formDataDomain.push(...getFormDataDomainByGrid(widget))
} else if (widget.type === 'tab') {
formDataDomain.push(...getFormDataDomainByTab(widget))
} else if (widget.type === 'card') {
formDataDomain.push(...getFormDataDomainByCard(widget))
}
} else {
formDataDomain.push(widget)
}
}
return formDataDomain
}
// 获取表格控件类型数据域
export function getFormDataDomainByTable(tableWidget) {
const formDataDomainByTable = []
tableWidget.rows.forEach(row => {
row.cols.forEach(col => {
formDataDomainByTable.push(...getFormDataDomain(col.widgetList))
})
})
return formDataDomainByTable;
}
// 获取网格控件类型数据域
export function getFormDataDomainByGrid(gridWidget) {
const formDataDomainByGrid = []
gridWidget.cols.forEach(col => {
formDataDomainByGrid.push(...getFormDataDomain(col.widgetList))
})
return formDataDomainByGrid;
}
// 获取标签页控件类型数据域
export function getFormDataDomainByTab(tabWidget) {
const formDataDomainByTab = []
tabWidget.tabs.forEach(tab => {
formDataDomainByTab.push(...getFormDataDomain(tab.widgetList))
})
return formDataDomainByTab;
}
// 获取卡片控件类型数据域
export function getFormDataDomainByCard(cardWidget) {
const formDataDomainByCard = []
formDataDomainByCard.push(...getFormDataDomain(cardWidget.widgetList))
return formDataDomainByCard;
}
3. 使用示例
// 获取表单控件数据域
const formDataDomain = getFormDataDomain(widgetList)
4. 结尾
我使用的是开源版 VForm,因此如果需要支持单行字表单、多行字表单等请自行处理。逻辑与表格、网格、标签页、卡片类似,这里不再赘述。