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

207 lines
7.2 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: '120px'
}
}
},
wrapperCol: () => {
return {
span: 18
}
},
labelAlign: "left",
colon: undefined,
disabled: undefined,
hideRequiredMark: undefined,
labelWrap: undefined,
scrollToFirstError: undefined,
validateOnRuleChange: undefined
})
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>