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>>()
|
const elFormRef = ref<ComponentRef<typeof ElForm>>()
|
||||||
|
|
||||||
// useForm传入的props
|
// useForm传入的props
|
||||||
const outsideProps = ref<FormProps>({ ...props })
|
const outsideProps = ref<FormProps>({})
|
||||||
|
|
||||||
const getProps = computed(() => {
|
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 = {}) => {
|
const setProps = (props: FormProps = {}) => {
|
||||||
outsideProps.value = Object.assign(unref(formModel), props)
|
outsideProps.value = props
|
||||||
}
|
}
|
||||||
|
|
||||||
const delSchema = (field: string) => {
|
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 = {}) => {
|
setProps: async (props: FormProps = {}) => {
|
||||||
const form = await getForm()
|
const form = await getForm()
|
||||||
console.log(form)
|
|
||||||
form?.setProps(props)
|
form?.setProps(props)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,9 @@ export default {
|
||||||
tagsView: 'Tags view',
|
tagsView: 'Tags view',
|
||||||
tagsViewDes: 'Used to record routing history',
|
tagsViewDes: 'Used to record routing history',
|
||||||
tool: 'Tool',
|
tool: 'Tool',
|
||||||
toolDes: 'Used to set up custom systems'
|
toolDes: 'Used to set up custom systems',
|
||||||
|
query: 'Query',
|
||||||
|
reset: 'Reset'
|
||||||
},
|
},
|
||||||
setting: {
|
setting: {
|
||||||
projectSetting: 'Project setting',
|
projectSetting: 'Project setting',
|
||||||
|
@ -95,7 +97,8 @@ export default {
|
||||||
highlight: 'Highlight',
|
highlight: 'Highlight',
|
||||||
infotip: 'Infotip',
|
infotip: 'Infotip',
|
||||||
form: 'Form',
|
form: 'Form',
|
||||||
defaultForm: 'All examples'
|
defaultForm: 'All examples',
|
||||||
|
search: 'Search'
|
||||||
},
|
},
|
||||||
analysis: {
|
analysis: {
|
||||||
newUser: 'New user',
|
newUser: 'New user',
|
||||||
|
@ -280,5 +283,21 @@ export default {
|
||||||
},
|
},
|
||||||
levelDemo: {
|
levelDemo: {
|
||||||
menu: 'Multi level menu cache'
|
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: '标签页',
|
tagsView: '标签页',
|
||||||
tagsViewDes: '用于记录路由历史记录',
|
tagsViewDes: '用于记录路由历史记录',
|
||||||
tool: '工具',
|
tool: '工具',
|
||||||
toolDes: '用于设置定制系统'
|
toolDes: '用于设置定制系统',
|
||||||
|
query: '查询',
|
||||||
|
reset: '重置'
|
||||||
},
|
},
|
||||||
setting: {
|
setting: {
|
||||||
projectSetting: '项目配置',
|
projectSetting: '项目配置',
|
||||||
|
@ -95,7 +97,8 @@ export default {
|
||||||
highlight: '高亮',
|
highlight: '高亮',
|
||||||
infotip: '信息提示',
|
infotip: '信息提示',
|
||||||
form: '表单',
|
form: '表单',
|
||||||
defaultForm: '全部示例'
|
defaultForm: '全部示例',
|
||||||
|
search: '查询'
|
||||||
},
|
},
|
||||||
analysis: {
|
analysis: {
|
||||||
newUser: '新增用户',
|
newUser: '新增用户',
|
||||||
|
@ -278,5 +281,20 @@ export default {
|
||||||
},
|
},
|
||||||
levelDemo: {
|
levelDemo: {
|
||||||
menu: '多级菜单缓存'
|
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',
|
path: 'icon',
|
||||||
component: () => import('@/views/Components/Icon.vue'),
|
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