|
|
|
@ -1,6 +1,6 @@ |
|
|
|
<script setup lang="ts"> |
|
|
|
import lodash from "lodash"; |
|
|
|
import { getCurrentInstance, reactive } from "vue"; |
|
|
|
import { computed, getCurrentInstance, onMounted, reactive, watch } from "vue"; |
|
|
|
import { breakpointsTailwind, useBreakpoints } from "@vueuse/core"; |
|
|
|
import { Expression, Typeof } from "@ease-forge/shared"; |
|
|
|
import { calcBreakpointValue, toVNode } from "@/utils/Utils.ts"; |
|
|
|
@ -60,6 +60,21 @@ const data: DataFormData = { |
|
|
|
|
|
|
|
// 响应式断点 |
|
|
|
const breakpoints = useBreakpoints(props.breakpoints ?? breakpointsTailwind); |
|
|
|
// 表单行内容 |
|
|
|
const formRows = computed(() => getFormRows(state.dataFormItems, state.columnCount)); |
|
|
|
|
|
|
|
// 监听响应式断点 |
|
|
|
if (Typeof.isObj(props.columnCount)) { |
|
|
|
watch(breakpoints.current(), current => state.columnCount = calcColumnCount(props.columnCount, current), { immediate: true }); |
|
|
|
} |
|
|
|
// 加载数据 |
|
|
|
// if (props.autoLoadData && props.dataApi) reload().finally(); |
|
|
|
// 监听data |
|
|
|
// watch(() => state.data, newData => dataChange(state.dataFormItems, newData), { immediate: true, deep: true }); |
|
|
|
// 监听loading |
|
|
|
watch(() => state.loading, loading => emit("loadingChange", loading)); |
|
|
|
// 设置ctxData(表单上下文数据) |
|
|
|
onMounted(() => data.ctxData.instance = instance!); |
|
|
|
|
|
|
|
/** bothFixed:label和input都固定宽度布局 */ |
|
|
|
function isBothFixed() { |
|
|
|
@ -150,6 +165,82 @@ function resolveInputComponent(input: any) { |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 根据 dataFormItems 和 columnCount 配置计算出表单行渲染内容 |
|
|
|
* @param dataFormItems 表单项数组 |
|
|
|
* @param columnCount 一行显示的字段数量 |
|
|
|
*/ |
|
|
|
function getFormRows(dataFormItems: Array<DataFormItem>, columnCount: number) { |
|
|
|
if (columnCount < 1) columnCount = 1; |
|
|
|
const formRows: Array<Array<DataFormItem>> = []; |
|
|
|
let formRow: Array<DataFormItem> | undefined; |
|
|
|
let columnIndex = 0; |
|
|
|
for (let formItem of dataFormItems) { |
|
|
|
if (formItem.hidden) { |
|
|
|
continue; |
|
|
|
} |
|
|
|
// 第一行 |
|
|
|
if (!formRow) { |
|
|
|
formRow = []; |
|
|
|
formRows.push(formRow); |
|
|
|
} |
|
|
|
// 判断是否需要换行 |
|
|
|
if (columnIndex >= columnCount) { |
|
|
|
columnIndex = 0; |
|
|
|
formRow = []; |
|
|
|
formRows.push(formRow); |
|
|
|
} |
|
|
|
// 当前行剩下的列数 |
|
|
|
const leftOverColumnCount = columnCount - columnIndex; |
|
|
|
// 当前数据需要占用的列数 |
|
|
|
let currentColumnCount = Math.min(formItem.widthCount, columnCount); |
|
|
|
// 剩下的列数不足以放下当前表单项,需要换行 |
|
|
|
if (currentColumnCount > leftOverColumnCount) { |
|
|
|
columnIndex = 0; |
|
|
|
formRow = []; |
|
|
|
formRows.push(formRow); |
|
|
|
} |
|
|
|
// 增加列索引 |
|
|
|
columnIndex += currentColumnCount; |
|
|
|
// formItem 加入当前行 |
|
|
|
formRow.push(formItem); |
|
|
|
} |
|
|
|
// 增加 submit 区域 |
|
|
|
if (slots.submit && formRows.length > 0) { |
|
|
|
formRow = formRows[formRows.length - 1]; |
|
|
|
const nextRow = formRow.length >= columnCount; |
|
|
|
const submitFormItem: DataFormItem = { |
|
|
|
widthCount: nextRow ? columnCount : columnCount - formRow.length, |
|
|
|
inputRef: "__submit", |
|
|
|
input: slots.submit, |
|
|
|
inputProps: {}, |
|
|
|
formItemProps: { |
|
|
|
autoLink: false, |
|
|
|
...props.submitFormItemProps, |
|
|
|
}, |
|
|
|
}; |
|
|
|
if (nextRow) { |
|
|
|
formRows.push([submitFormItem]); |
|
|
|
} else { |
|
|
|
// 优化 submit 区域与上一个字段直接的间距 |
|
|
|
if (!submitFormItem.formItemProps.style) submitFormItem.formItemProps.style = {}; |
|
|
|
if (!submitFormItem.formItemProps.style.paddingLeft && !submitFormItem.formItemProps.style["padding-left"]) { |
|
|
|
submitFormItem.formItemProps.style.paddingLeft = "12px"; |
|
|
|
} |
|
|
|
formRow.push(submitFormItem); |
|
|
|
} |
|
|
|
// 优化表单只有单行时的 submit 区域宽度(更加自然合理) |
|
|
|
if (formRows.length === 1) { |
|
|
|
if (submitFormItem.formItemProps.class) { |
|
|
|
submitFormItem.formItemProps.class = `${submitFormItem.formItemProps.class} data-form-item-auto`; |
|
|
|
} else { |
|
|
|
submitFormItem.formItemProps.class = "data-form-item-auto"; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
return formRows; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 根据响应式断点配置,计算一行显示的字段数量 |
|
|
|
* @param columnCount 响应式断点配置 |
|
|
|
* @param current 当前响应式断点值 |
|
|
|
@ -178,7 +269,9 @@ export type { |
|
|
|
|
|
|
|
<template> |
|
|
|
<div class="data-form"> |
|
|
|
<Loading> |
|
|
|
|
|
|
|
</Loading> |
|
|
|
</div> |
|
|
|
</template> |
|
|
|
|
|
|
|
|