@@ -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 '@/type s/f orm'
import { initModel } from '@/component s/F orm/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' ) ,
// 底部按钮的对齐方式
buttom Position : propTypes . string
button Position : 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 ( in dex + 1 , length )
}
schema . map ( ( v , i ) => {
if ( i > = index ) {
v . hid den = 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 botton ButtonStyle = computed ( ( ) => {
const bottom ButtonStyle = computed ( ( ) => {
return {
textAlign : props . buttom Position as unknown as 'left' | 'center' | 'right'
textAlign : props . button Position 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 = "botton ButtonStyle" >
< ElButton v-if = "showSearch" type="primary" @click="search" >
< Icon icon = "ep:s earch" class = "mr-5px" / >
< div :style = "bottom ButtonStyle" >
< ElButton
v-if = "showS earch"
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 >