Files
MrleeAdmin/frontend/admin/src/components/search-bar/search-bar.vue
T

241 lines
7.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<SearchBar
ref="formRef"
:show-reset="formSchemaRef.showResetButton"
:show-search="formSchemaRef.showSubmitButton"
:show-expand="formSchemaRef.showExpandButton"
:label-position="formSchemaRef.labelPosition"
:label-width="formSchemaRef.labelWidth"
:gutter="formSchemaRef.gutter"
:span="formSchemaRef.span"
:is-expand="formSchemaRef.isExpand"
:items="cItems"
v-model="searchFormState"
@search="handleSearch"
@reset="handleReset"
>
<template v-for="schema in filteredSchema" :key="schema.prop" #[schema.prop]>
<component
:ref="(obj: any) => setComponentRef(schema.prop, obj)"
:is="getComponent(schema.component)"
v-model:value="searchFormState[schema.prop]"
v-bind="schema.componentProps"
></component>
</template>
</SearchBar>
</template>
<script setup lang="ts">
import SearchBar from '@/components/core/forms/art-search-bar/index.vue'
import { FormInstance, FormItemSchema, FormSchema } from '../form'
import { getComponent, hasComponent } from '../form/component-map'
const props = withDefaults(
defineProps<{
formSchema: FormSchema
formMethods?: any
}>(),
{
formSchema: () => {
return {
schema: []
}
}
}
)
const emit = defineEmits<{
(e: 'submit', values: any): void
(e: 'reset'): void
(e: 'register', formInstance: FormInstance): void
(e: 'change', values: any): void
}>()
const formSchemaRef = ref<FormSchema>(props.formSchema)
const componentRef = reactive<Record<string, any>>({})
const setComponentRef = (field: string, ref: any) => {
componentRef[field] = ref
}
const handleSearch = () => {
emit('submit', searchFormState)
}
const handleReset = () => {
emit('reset')
}
const formRef = ref()
const searchFormState = reactive<any>({})
const cItems = computed(() => {
return (
props.formSchema.schema?.map((item: any) => {
return {
...item,
key: item.prop,
type: item.component,
span: item.colSpan,
width: item.searchWidth,
props: item.componentProps
}
}) || []
)
})
// 过滤出有有效组件的schema
const filteredSchema = computed(() => {
return (props.formSchema.schema || []).filter((schema: any) => hasComponent(schema.component))
})
// 提取公共的表单实例方法到一个常量对象
const formInstanceMethods: FormInstance = {
// Element Plus 表单的原生方法
validate(callback?: (valid: boolean, fields?: any) => void) {
return formRef.value?.validate(callback)
},
validateField(props?: string | string[], callback?: (valid: boolean, fields?: any) => void) {
if (formRef.value?.validateField) {
return formRef.value.validateField(props, callback)
}
return Promise.resolve()
},
resetFields(props?: string | string[]) {
formRef.value?.resetFields(props)
// 重置特定字段后,为这些字段重新设置默认值(如果它们没有被设置)
if (props) {
const propList = Array.isArray(props) ? props : [props]
const schema = formSchemaRef.value.schema || []
propList.forEach((prop) => {
const item = schema.find((s) => s.prop === prop)
if (item && searchFormState[prop] === undefined) {
searchFormState[prop] = item.defaultValue !== undefined ? item.defaultValue : undefined
}
})
}
},
clearValidate(props?: string | string[]) {
formRef.value?.clearValidate(props)
},
scrollToField(prop: string) {
formRef.value?.scrollToField(prop)
},
// 自定义方法
getValues() {
// 通过schema来遍历key获取表单值(包含show隐藏但仍存在于DOM中的字段)
const values: Record<string, any> = {}
const schema = props.formSchema.schema || []
schema.forEach((item) => {
// 处理ifShow字段(js控制是否渲染)
const shouldRender =
item.ifShow === undefined ||
(typeof item.ifShow === 'function'
? item.ifShow(searchFormState, props.formMethods)
: item.ifShow)
// 只有在DOM中渲染的字段才获取值(无论是否CSS隐藏)
if (shouldRender) {
values[item.prop] = searchFormState[item.prop]
}
})
return Promise.resolve(values)
},
getFormRef() {
return formRef.value
},
setValues(fields, filterFields, shouldValidate) {
return new Promise<void>((resolve) => {
// 获取 schema 中定义的所有字段名
const schemaProps = (props.formSchema.schema || []).map((item) => item.prop)
// 处理字段值设置
Object.keys(fields).forEach((key) => {
// 如果启用过滤,则只设置在 schema 中定义的字段
if (!filterFields || schemaProps.includes(key)) {
searchFormState[key] = fields[key]
}
})
// 如果需要触发验证
if (shouldValidate) {
formRef.value
?.validate()
.then(() => {
resolve()
})
.catch(() => {
resolve()
})
} else {
resolve()
}
})
},
// 获取字段组件实例
getFieldComponentRef(field: string) {
return componentRef[field]
},
// 设置组件状态(props)
setState(state: FormSchema) {
return new Promise((resolve) => {
formSchemaRef.value = {
...formSchemaRef.value,
...state
}
nextTick(() => {
resolve()
})
})
},
getState(): Promise<FormSchema> {
return new Promise((resolve) => {
resolve(formSchemaRef.value)
})
},
updateSchema(data: Partial<FormItemSchema> | Partial<FormItemSchema>[]) {
return new Promise<void>((resolve) => {
// 确保 data 是数组格式
const updateData = Array.isArray(data) ? data : [data]
// 创建一个 prop 到 schema 项的映射,方便查找
const schemaMap = new Map<string, FormItemSchema>()
formSchemaRef.value.schema?.forEach((item) => {
schemaMap.set(item.prop, item)
})
// 更新对应的 schema 项
updateData.forEach((item) => {
if (item.prop && schemaMap.has(item.prop)) {
const index = formSchemaRef.value.schema!.findIndex(
(schemaItem) => schemaItem.prop === item.prop
)
if (index !== -1) {
// 合并原有的配置和新的配置
formSchemaRef.value.schema![index] = {
...formSchemaRef.value.schema![index],
...item
}
// 如果更新了defaultValue且当前字段值为undefined,则设置默认值
if (
Object.prototype.hasOwnProperty.call(item, 'defaultValue') &&
searchFormState[item.prop] === undefined
) {
searchFormState[item.prop] = item.defaultValue
}
}
}
})
nextTick(() => {
resolve()
})
})
}
}
// 注册表单实例
onMounted(() => {
emit('register', formInstanceMethods)
})
</script>
<style lang="less" scoped></style>