policeSecurity/policeManagement/src/components/form/FormProMax.vue

173 lines
6.8 KiB
Vue

<template>
<a-form ref="formProMaxRef" v-bind="props" :model="modelValue">
<a-row :gutter="props.gutter">
<a-col v-for="(item,field) in props.formItemOptions as FormProMaxItemOptions<T>" :key="field" v-bind="getResponsive(item)">
<a-form-item :name="field" v-bind="item" :label="undefined">
<template v-slot:label>
{{ item.label }}
<template v-if="item.remarkRender">
<a-popover :title="item.label" :content="item.remarkRender()">
<QuestionCircleOutlined class="margin-left-xs" style="color: red" />
</a-popover>
</template>
</template>
<!-- 自定义组件 -->
<!-- ant design vue 组件 -->
<a-input
v-if="item.type === 'input'"
v-model:value="modelValue[field]"
style="width: 100%"
v-bind="item.componentsProps"
:placeholder="getPlaceholder(item)"
:allowClear="item.componentsProps?.allowClear ?? true"
/>
<a-input-password
v-else-if="item.type === 'inputPassword'"
v-model:value="modelValue[field]"
style="width: 100%"
v-bind="item.componentsProps"
:placeholder="getPlaceholder(item)"
:allowClear="item.componentsProps?.allowClear ?? true"
/>
<a-input-number v-else-if="item.type === 'inputNumber'" v-model:value="modelValue[field]" style="width: 100%" v-bind="item.componentsProps" :placeholder="getPlaceholder(item)" />
<a-textarea
v-else-if="item.type === 'inputTextArea'"
v-model:value="modelValue[field]"
style="width: 100%"
v-bind="item.componentsProps"
:placeholder="getPlaceholder(item)"
:allowClear="item.componentsProps?.allowClear ?? true"
/>
<a-radio-group v-else-if="item.type === 'radioGroup'" v-model:value="modelValue[field]" style="width: 100%" v-bind="item.componentsProps" :options="item.options" />
<a-checkbox-group v-else-if="item.type === 'checkboxGroup'" v-model:value="modelValue[field]" style="width: 100%" v-bind="item.componentsProps" :options="item.options" />
<a-select
v-else-if="item.type === 'select'"
v-model:value="modelValue[field]"
style="width: 100%"
v-bind="item.componentsProps"
:placeholder="getPlaceholder(item)"
:allowClear="item.componentsProps?.allowClear ?? true"
:options="item.options"
/>
<a-tree-select
v-else-if="item.type === 'treeSelect'"
style="width: 100%"
v-model:value="modelValue[field]"
v-bind="item.componentsProps"
:placeholder="getPlaceholder(item)"
:allowClear="item.componentsProps?.allowClear ?? true"
:tree-data="item.options"
/>
<a-cascader
v-else-if="item.type === 'cascader'"
style="width: 100%"
v-model:value="modelValue[field]"
v-bind="item.componentsProps"
:placeholder="getPlaceholder(item)"
:allowClear="item.componentsProps?.allowClear ?? true"
:options="item.options"
/>
<a-range-picker
v-else-if="item.type === 'rangePicker'"
style="width: 100%"
v-model:value="modelValue[field]"
v-bind="item.componentsProps"
:placeholder="item.componentsProps?.placeholder ?? ['开始日期', '结束日期']"
:allowClear="item.componentsProps?.allowClear ?? true"
/>
<a-date-picker
v-else-if="item.type === 'datePicker'"
style="width: 100%"
v-model:value="modelValue[field]"
v-bind="item.componentsProps"
:placeholder="item.componentsProps?.placeholder ?? '请选择日期'"
:allowClear="item.componentsProps?.allowClear ?? true"
/>
<a-time-range-picker
v-else-if="item.type === 'timeRangePicker'"
style="width: 100%"
v-model:value="modelValue[field]"
v-bind="item.componentsProps"
:placeholder="item.componentsProps?.placeholder ?? ['开始时间', '结束时间']"
:allowClear="item.componentsProps?.allowClear ?? true"
/>
<a-time-picker
v-else-if="item.type === 'timePicker'"
style="width: 100%"
v-model:value="modelValue[field]"
v-bind="item.componentsProps"
:placeholder="getPlaceholder(item)"
:allowClear="item.componentsProps?.allowClear ?? true"
/>
<template v-else-if="item.type === 'custom'">
<component :is="item.customRender" />
</template>
</a-form-item>
</a-col>
</a-row>
<slot name="formOperation"></slot>
</a-form>
</template>
<script setup lang="ts" generic="T extends Record<string,any>">
import { FormInstance } from 'ant-design-vue'
import { ref } from 'vue'
import { FormExpose } from 'ant-design-vue/es/form/Form'
import { QuestionCircleOutlined } from '@ant-design/icons-vue'
import { FormProMaxItemOptions, FormProMaxItemProps, FormProMaxProps } from '@/types/components/form/index.ts'
const modelValue = defineModel<T>('value', {
default: {},
})
const props = withDefaults(defineProps<FormProMaxProps<T>>(), {
grid: () => {
return {
span: 24,
}
},
gutter: 10,
labelCol: () => {
return {
style: {
width: '100px',
},
}
},
wrapperCol: () => {
return {
span: 18,
}
},
labelAlign: 'left',
colon: undefined,
disabled: undefined,
hideRequiredMark: undefined,
labelWrap: undefined,
scrollToFirstError: undefined,
validateOnRuleChange: undefined,
})
console.log(props)
const formProMaxRef = ref<FormInstance>(null!)
const getResponsive = (item: FormProMaxItemProps): Grid => {
//span优先级高于响应式设置
if (item.grid) return item.grid.span ? { span: item.grid.span } : { ...item.grid }
return { ...props.grid }
}
//优先级: 组件本身=》formItem=》label
const getPlaceholder = (item: FormProMaxItemProps) => item.componentsProps?.placeholder ?? item.placeholder ?? (item.type.includes('input') ? `请输入${item.label}` : `请选择${item.label}`)
defineExpose<FormExpose>({
validate: (nameList, options) => formProMaxRef.value?.validate(nameList, options),
resetFields: (name) => formProMaxRef.value?.resetFields(name),
clearValidate: () => formProMaxRef.value?.clearValidate(),
getFieldsValue: (nameList) => formProMaxRef.value?.getFieldsValue(nameList),
scrollToField: (name, options) => formProMaxRef.value?.scrollToField(name, options),
validateFields: (nameList, options) => formProMaxRef.value?.validateFields(nameList, options),
})
</script>
<style scoped></style>