wip: Search重构中

This commit is contained in:
kailong321200875
2023-06-21 17:59:37 +08:00
parent 77a3866248
commit c76f8bc494
8 changed files with 293 additions and 135 deletions

View File

@@ -1,16 +1,19 @@
<script setup lang="ts">
import { Form } from '@/components/Form'
import { PropType, computed, unref, ref } from 'vue'
<script setup lang="tsx">
import { Form, FormSchema } from '@/components/Form'
import { PropType, computed, unref, ref, watch, onMounted } from 'vue'
import { propTypes } from '@/utils/propTypes'
import { ElButton } from 'element-plus'
import { useI18n } from '@/hooks/web/useI18n'
import { useForm } from '@/hooks/web/useForm'
import { useIcon } from '@/hooks/web/useIcon'
import { findIndex } from '@/utils'
import { cloneDeep } from 'lodash-es'
import { FormSchema } from '@/types/form'
import { initModel } from '@/components/Form/src/helper'
const { t } = useI18n()
const formExpose = ref<ComponentRef<typeof Form>>()
const props = defineProps({
// 生成Form的布局结构数组
schema: {
@@ -24,7 +27,7 @@ const props = defineProps({
// 操作按钮风格位置
layout: propTypes.string.validate((v: string) => ['inline', 'bottom'].includes(v)).def('inline'),
// 底部按钮的对齐方式
buttomPosition: propTypes.string
buttonPosition: propTypes.string
.validate((v: string) => ['left', 'center', 'right'].includes(v))
.def('center'),
showSearch: propTypes.bool.def(true),
@@ -34,31 +37,69 @@ const props = defineProps({
// 伸缩的界限字段
expandField: propTypes.string.def(''),
inline: propTypes.bool.def(true),
// 是否去除空值项
removeNoValueItem: propTypes.bool.def(true),
model: {
type: Object as PropType<Recordable>,
default: () => ({})
}
})
const emit = defineEmits(['search', 'reset'])
const emit = defineEmits(['search', 'reset', 'register'])
const visible = ref(true)
// 表单数据
const formModel = ref<Recordable>({})
const newSchema = computed(() => {
let schema: FormSchema[] = cloneDeep(props.schema)
if (props.expand && props.expandField && !unref(visible)) {
const index = findIndex(schema, (v: FormSchema) => v.field === props.expandField)
if (index > -1) {
const length = schema.length
schema.splice(index + 1, length)
}
schema.map((v, i) => {
if (i >= index) {
v.hidden = true
} else {
v.hidden = false
}
return v
})
}
if (props.layout === 'inline') {
schema = schema.concat([
{
field: 'action',
formItemProps: {
labelWidth: '0px'
labelWidth: '0px',
slots: {
default: () => {
return (
<div>
{props.showSearch ? (
<ElButton type="primary" onClick={search} icon={useIcon({ icon: 'ep:search' })}>
{t('common.query')}
</ElButton>
) : null}
{props.showReset ? (
<ElButton onClick={reset} icon={useIcon({ icon: 'ep:refresh-right' })}>
{t('common.reset')}
</ElButton>
) : null}
{props.expand ? (
<ElButton
text
onClick={setVisible}
icon={useIcon({
icon: visible.value ? 'ant-design:up-outlined' : 'ant-design:down-outlined'
})}
>
{t(visible.value ? 'common.shrink' : 'common.expand')}
</ElButton>
) : null}
</div>
)
}
}
}
}
])
@@ -66,41 +107,69 @@ const newSchema = computed(() => {
return schema
})
const { register, elFormRef, methods } = useForm({
model: props.model || {}
})
const { register, methods } = useForm()
const { getElFormExpose, getFormData } = methods
// 监听表单结构化数组重新生成formModel
watch(
() => unref(newSchema),
async (schema = []) => {
formModel.value = initModel(schema, unref(formModel))
},
{
immediate: true,
deep: true
}
)
const filterModel = async () => {
const model = await getFormData()
props.removeNoValueItem &&
Object.keys(model).forEach((key) => {
if (model[key] === void 0 || model[key] === '') {
delete model[key]
}
})
return model
}
const search = async () => {
await unref(elFormRef)?.validate(async (isValid) => {
const elFormExpose = await getElFormExpose()
await elFormExpose?.validate(async (isValid) => {
if (isValid) {
const { getFormData } = methods
const model = await getFormData()
const model = await filterModel()
emit('search', model)
}
})
}
const reset = async () => {
unref(elFormRef)?.resetFields()
const { getFormData } = methods
const model = await getFormData()
const elFormExpose = await getElFormExpose()
elFormExpose?.resetFields()
const model = await filterModel()
emit('reset', model)
}
const bottonButtonStyle = computed(() => {
const bottomButtonStyle = computed(() => {
return {
textAlign: props.buttomPosition as unknown as 'left' | 'center' | 'right'
textAlign: props.buttonPosition as unknown as 'left' | 'center' | 'right'
}
})
const setVisible = () => {
unref(elFormRef)?.resetFields()
const setVisible = async () => {
visible.value = !unref(visible)
}
onMounted(async () => {
const elFormExpose = await getElFormExpose()
emit('register', formExpose, elFormExpose)
})
</script>
<template>
<Form
ref="formExpose"
:model="formModel"
:is-custom="false"
:label-width="labelWidth"
hide-required-asterisk
@@ -108,38 +177,28 @@ const setVisible = () => {
:is-col="isCol"
:schema="newSchema"
@register="register"
>
<template #action>
<div v-if="layout === 'inline'">
<ElButton v-if="showSearch" type="primary" @click="search">
<Icon icon="ep:search" class="mr-5px" />
{{ t('common.query') }}
</ElButton>
<ElButton v-if="showReset" @click="reset">
<Icon icon="ep:refresh-right" class="mr-5px" />
{{ t('common.reset') }}
</ElButton>
<ElButton v-if="expand" text @click="setVisible">
{{ t(visible ? 'common.shrink' : 'common.expand') }}
<Icon :icon="visible ? 'ant-design:up-outlined' : 'ant-design:down-outlined'" />
</ElButton>
</div>
</template>
</Form>
/>
<template v-if="layout === 'bottom'">
<div :style="bottonButtonStyle">
<ElButton v-if="showSearch" type="primary" @click="search">
<Icon icon="ep:search" class="mr-5px" />
<div :style="bottomButtonStyle">
<ElButton
v-if="showSearch"
type="primary"
:icon="useIcon({ icon: 'ep:search' })"
@click="search"
>
{{ t('common.query') }}
</ElButton>
<ElButton v-if="showReset" @click="reset">
<Icon icon="ep:refresh-right" class="mr-5px" />
<ElButton v-if="showReset" :icon="useIcon({ icon: 'ep:refresh-right' })" @click="reset">
{{ t('common.reset') }}
</ElButton>
<ElButton v-if="expand" text @click="setVisible">
<ElButton
v-if="expand"
:icon="useIcon({ icon: visible ? 'ant-design:up-outlined' : 'ant-design:down-outlined' })"
text
@click="setVisible"
>
{{ t(visible ? 'common.shrink' : 'common.expand') }}
<Icon :icon="visible ? 'ant-design:up-outlined' : 'ant-design:down-outlined'" />
</ElButton>
</div>
</template>