feat: Add Search component and add search demo
This commit is contained in:
parent
8a958cd71d
commit
33eca8a97d
|
@ -52,10 +52,16 @@ export default defineComponent({
|
|||
const elFormRef = ref<ComponentRef<typeof ElForm>>()
|
||||
|
||||
// useForm传入的props
|
||||
const outsideProps = ref<FormProps>({ ...props })
|
||||
const outsideProps = ref<FormProps>({})
|
||||
|
||||
const getProps = computed(() => {
|
||||
return { ...props, ...unref(outsideProps) }
|
||||
const propsObj = { ...props }
|
||||
for (const key in unref(outsideProps)) {
|
||||
if (Reflect.has(propsObj, key)) {
|
||||
propsObj[key] = unref(outsideProps)[key]
|
||||
}
|
||||
}
|
||||
return propsObj
|
||||
})
|
||||
|
||||
// 表单数据
|
||||
|
@ -71,7 +77,7 @@ export default defineComponent({
|
|||
}
|
||||
|
||||
const setProps = (props: FormProps = {}) => {
|
||||
outsideProps.value = Object.assign(unref(formModel), props)
|
||||
outsideProps.value = props
|
||||
}
|
||||
|
||||
const delSchema = (field: string) => {
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
import Search from './src/Search.vue'
|
||||
|
||||
export { Search }
|
|
@ -0,0 +1,106 @@
|
|||
<script setup lang="ts">
|
||||
import { Form } from '@/components/Form'
|
||||
import { PropType, computed, unref, CSSProperties } from 'vue'
|
||||
import { propTypes } from '@/utils/propTypes'
|
||||
import { ElButton } from 'element-plus'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import { useForm } from '@/hooks/web/useForm'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const props = defineProps({
|
||||
// 生成Form的布局结构数组
|
||||
schema: {
|
||||
type: Array as PropType<FormSchema[]>,
|
||||
default: () => []
|
||||
},
|
||||
// 是否需要栅格布局
|
||||
isCol: propTypes.bool.def(false),
|
||||
// 表单label宽度
|
||||
labelWidth: propTypes.oneOfType([String, Number]).def('auto'),
|
||||
// 操作按钮风格位置
|
||||
layout: propTypes.string.validate((v: string) => ['inline', 'bottom'].includes(v)).def('inline'),
|
||||
// 底部按钮的对齐方式
|
||||
buttomPosition: propTypes.string
|
||||
.validate((v: string) => ['left', 'center', 'right'].includes(v))
|
||||
.def('center'),
|
||||
showSearch: propTypes.bool.def(true),
|
||||
showReset: propTypes.bool.def(true)
|
||||
})
|
||||
|
||||
const emit = defineEmits(['search', 'reset'])
|
||||
|
||||
const newSchema = computed(() => {
|
||||
if (props.layout === 'inline') {
|
||||
return props.schema.concat([
|
||||
{
|
||||
field: 'action',
|
||||
formItemProps: {
|
||||
labelWidth: '0px'
|
||||
}
|
||||
}
|
||||
])
|
||||
} else {
|
||||
return props.schema
|
||||
}
|
||||
})
|
||||
|
||||
const { register, elFormRef, methods } = useForm()
|
||||
|
||||
const search = async () => {
|
||||
const res = await unref(elFormRef)
|
||||
?.validate()
|
||||
?.catch(() => {})
|
||||
if (res) {
|
||||
const { getFormData } = methods
|
||||
const model = await getFormData()
|
||||
emit('search', model)
|
||||
}
|
||||
}
|
||||
|
||||
const reset = async () => {
|
||||
unref(elFormRef)?.resetFields()
|
||||
const { getFormData } = methods
|
||||
const model = await getFormData()
|
||||
emit('reset', model)
|
||||
}
|
||||
|
||||
const bottonButtonStyle = computed(() => {
|
||||
return {
|
||||
textAlign: props.buttomPosition
|
||||
}
|
||||
}) as CSSProperties
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Form
|
||||
:is-custom="false"
|
||||
:label-width="labelWidth"
|
||||
hide-required-asterisk
|
||||
inline
|
||||
:is-col="isCol"
|
||||
:schema="newSchema"
|
||||
@register="register"
|
||||
>
|
||||
<template v-if="layout === 'inline'" #action>
|
||||
<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>
|
||||
</template>
|
||||
</Form>
|
||||
<div v-if="layout === 'bottom'" :style="bottonButtonStyle">
|
||||
<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>
|
||||
</div>
|
||||
</template>
|
|
@ -39,7 +39,6 @@ export const useForm = (props?: FormProps) => {
|
|||
} = {
|
||||
setProps: async (props: FormProps = {}) => {
|
||||
const form = await getForm()
|
||||
console.log(form)
|
||||
form?.setProps(props)
|
||||
},
|
||||
|
||||
|
|
|
@ -29,7 +29,9 @@ export default {
|
|||
tagsView: 'Tags view',
|
||||
tagsViewDes: 'Used to record routing history',
|
||||
tool: 'Tool',
|
||||
toolDes: 'Used to set up custom systems'
|
||||
toolDes: 'Used to set up custom systems',
|
||||
query: 'Query',
|
||||
reset: 'Reset'
|
||||
},
|
||||
setting: {
|
||||
projectSetting: 'Project setting',
|
||||
|
@ -95,7 +97,8 @@ export default {
|
|||
highlight: 'Highlight',
|
||||
infotip: 'Infotip',
|
||||
form: 'Form',
|
||||
defaultForm: 'All examples'
|
||||
defaultForm: 'All examples',
|
||||
search: 'Search'
|
||||
},
|
||||
analysis: {
|
||||
newUser: 'New user',
|
||||
|
@ -280,5 +283,21 @@ export default {
|
|||
},
|
||||
levelDemo: {
|
||||
menu: 'Multi level menu cache'
|
||||
},
|
||||
searchDemo: {
|
||||
search: 'Search',
|
||||
searchDes:
|
||||
'Based on the secondary encapsulation of form components, the functions of query and reset are realized',
|
||||
operate: 'operate',
|
||||
change: 'Change',
|
||||
grid: 'grid',
|
||||
button: 'Button',
|
||||
restore: 'Restore',
|
||||
inline: 'inline',
|
||||
bottom: 'Bottom',
|
||||
position: 'position',
|
||||
left: 'left',
|
||||
center: 'center',
|
||||
right: 'right'
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,9 @@ export default {
|
|||
tagsView: '标签页',
|
||||
tagsViewDes: '用于记录路由历史记录',
|
||||
tool: '工具',
|
||||
toolDes: '用于设置定制系统'
|
||||
toolDes: '用于设置定制系统',
|
||||
query: '查询',
|
||||
reset: '重置'
|
||||
},
|
||||
setting: {
|
||||
projectSetting: '项目配置',
|
||||
|
@ -95,7 +97,8 @@ export default {
|
|||
highlight: '高亮',
|
||||
infotip: '信息提示',
|
||||
form: '表单',
|
||||
defaultForm: '全部示例'
|
||||
defaultForm: '全部示例',
|
||||
search: '查询'
|
||||
},
|
||||
analysis: {
|
||||
newUser: '新增用户',
|
||||
|
@ -278,5 +281,20 @@ export default {
|
|||
},
|
||||
levelDemo: {
|
||||
menu: '多级菜单缓存'
|
||||
},
|
||||
searchDemo: {
|
||||
search: '查询',
|
||||
searchDes: '基于 Form 组件二次封装,实现查询、重置功能',
|
||||
operate: '操作',
|
||||
change: '更改',
|
||||
grid: '栅格',
|
||||
button: '按钮',
|
||||
restore: '还原',
|
||||
inline: '内联',
|
||||
bottom: '底部',
|
||||
position: '位置',
|
||||
left: '左',
|
||||
center: '中',
|
||||
right: '右'
|
||||
}
|
||||
}
|
||||
|
|
|
@ -131,6 +131,14 @@ export const asyncRouterMap: AppRouteRecordRaw[] = [
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'search',
|
||||
component: () => import('@/views/Components/Search.vue'),
|
||||
name: 'Search',
|
||||
meta: {
|
||||
title: t('router.search')
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'icon',
|
||||
component: () => import('@/views/Components/Icon.vue'),
|
||||
|
|
|
@ -0,0 +1,114 @@
|
|||
<script setup lang="ts">
|
||||
import { ContentWrap } from '@/components/ContentWrap'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import { Search } from '@/components/Search'
|
||||
import { reactive, ref, unref } from 'vue'
|
||||
import { required } from '@/utils/formRules'
|
||||
import { ElButton } from 'element-plus'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const schema = reactive<FormSchema[]>([
|
||||
{
|
||||
field: 'field1',
|
||||
label: t('formDemo.input'),
|
||||
component: 'Input',
|
||||
formItemProps: {
|
||||
rules: [required]
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'field2',
|
||||
label: t('formDemo.select'),
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
options: [
|
||||
{
|
||||
label: 'option1',
|
||||
value: '1'
|
||||
},
|
||||
{
|
||||
label: 'option2',
|
||||
value: '2'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'field3',
|
||||
label: t('formDemo.radio'),
|
||||
component: 'Radio',
|
||||
componentProps: {
|
||||
options: [
|
||||
{
|
||||
label: 'option-1',
|
||||
value: '1'
|
||||
},
|
||||
{
|
||||
label: 'option-2',
|
||||
value: '2'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'field5',
|
||||
component: 'DatePicker',
|
||||
label: t('formDemo.datePicker'),
|
||||
componentProps: {
|
||||
type: 'date'
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'field6',
|
||||
component: 'TimeSelect',
|
||||
label: t('formDemo.timeSelect')
|
||||
}
|
||||
])
|
||||
|
||||
const isGrid = ref(false)
|
||||
|
||||
const changeGrid = (grid: boolean) => {
|
||||
isGrid.value = grid
|
||||
}
|
||||
|
||||
const layout = ref('inline')
|
||||
|
||||
const changeLayout = () => {
|
||||
layout.value = unref(layout) === 'inline' ? 'bottom' : 'inline'
|
||||
}
|
||||
|
||||
const buttomPosition = ref('left')
|
||||
|
||||
const changePosition = (position: string) => {
|
||||
layout.value = 'bottom'
|
||||
buttomPosition.value = position
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ContentWrap :title="`${t('searchDemo.search')} ${t('searchDemo.operate')}`">
|
||||
<ElButton @click="changeGrid(true)">{{ t('searchDemo.grid') }}</ElButton>
|
||||
<ElButton @click="changeGrid(false)">
|
||||
{{ t('searchDemo.restore') }} {{ t('searchDemo.grid') }}
|
||||
</ElButton>
|
||||
|
||||
<ElButton @click="changeLayout">
|
||||
{{ t('searchDemo.button') }} {{ t('searchDemo.position') }}
|
||||
</ElButton>
|
||||
|
||||
<ElButton @click="changePosition('left')">
|
||||
{{ t('searchDemo.bottom') }} {{ t('searchDemo.position') }}-{{ t('searchDemo.left') }}
|
||||
</ElButton>
|
||||
<ElButton @click="changePosition('center')">
|
||||
{{ t('searchDemo.bottom') }} {{ t('searchDemo.position') }}-{{ t('searchDemo.center') }}
|
||||
</ElButton>
|
||||
<ElButton @click="changePosition('right')">
|
||||
{{ t('searchDemo.bottom') }} {{ t('searchDemo.position') }}-{{ t('searchDemo.right') }}
|
||||
</ElButton>
|
||||
</ContentWrap>
|
||||
|
||||
<ContentWrap :title="t('searchDemo.search')" :message="t('searchDemo.searchDes')">
|
||||
<Search :schema="schema" :is-col="isGrid" :layout="layout" :buttom-position="buttomPosition" />
|
||||
</ContentWrap>
|
||||
</template>
|
Loading…
Reference in New Issue