From 745815f637e5385b2cbc23a6ae02401bb8b6c675 Mon Sep 17 00:00:00 2001 From: Ben Lin <maobin001@msn.com> Date: 星期六, 08 三月 2025 14:22:36 +0800 Subject: [PATCH] 详情页面优化 --- src/components/Icon/src/IconPicker.vue | 133 +++++++++++++++++++++++-------------------- 1 files changed, 71 insertions(+), 62 deletions(-) diff --git a/src/components/Icon/src/IconPicker.vue b/src/components/Icon/src/IconPicker.vue index adcf01a..935ccd0 100644 --- a/src/components/Icon/src/IconPicker.vue +++ b/src/components/Icon/src/IconPicker.vue @@ -1,13 +1,15 @@ <template> - <a-input - disabled + <Input :style="{ width }" :placeholder="t('component.icon.placeholder')" :class="prefixCls" v-model:value="currentSelect" + @click="triggerPopover" + :allowClear="props.allowClear" + :readonly="props.readonly" > <template #addonAfter> - <a-popover + <Popover placement="bottomLeft" trigger="click" v-model="visible" @@ -15,7 +17,7 @@ > <template #title> <div class="flex justify-between"> - <a-input + <Input :placeholder="t('component.icon.search')" @change="debounceHandleSearchChange" allowClear @@ -35,14 +37,13 @@ @click="handleClick(icon)" :title="icon" > - <!-- <Icon :icon="icon" :prefix="prefix" /> --> <SvgIcon v-if="isSvgMode" :name="icon" /> <Icon :icon="icon" v-else /> </li> </ul> </ScrollContainer> <div class="flex py-2 items-center justify-center" v-if="getTotal >= pageSize"> - <a-pagination + <Pagination showLessItems size="small" :pageSize="pageSize" @@ -51,64 +52,75 @@ /> </div> </div> - <template v-else - ><div class="p-5"><a-empty /></div> + <template v-else> + <div class="p-5"><Empty /> </div> </template> </template> - <span class="cursor-pointer px-2 py-1 flex items-center" v-if="isSvgMode && currentSelect"> - <SvgIcon :name="currentSelect" /> - </span> - <Icon :icon="currentSelect || 'ion:apps-outline'" class="cursor-pointer px-2 py-1" v-else /> - </a-popover> + <div ref="trigger"> + <span + class="cursor-pointer px-2 py-1 flex items-center" + v-if="isSvgMode && currentSelect" + > + <SvgIcon :name="currentSelect" /> + </span> + <Icon + :icon="currentSelect || 'ion:apps-outline'" + class="cursor-pointer px-2 py-1" + v-else + /> + </div> + </Popover> </template> - </a-input> + </Input> </template> <script lang="ts" setup> - import { ref, watchEffect, watch, unref } from 'vue'; - import { useDesign } from '/@/hooks/web/useDesign'; - import { ScrollContainer } from '/@/components/Container'; + import { ref, watchEffect, watch } from 'vue'; + import { useDesign } from '@/hooks/web/useDesign'; + import { ScrollContainer } from '@/components/Container'; import { Input, Popover, Pagination, Empty } from 'ant-design-vue'; import Icon from '../Icon.vue'; import SvgIcon from './SvgIcon.vue'; import iconsData from '../data/icons.data'; - import { propTypes } from '/@/utils/propTypes'; - import { usePagination } from '/@/hooks/web/usePagination'; + import { usePagination } from '@/hooks/web/usePagination'; import { useDebounceFn } from '@vueuse/core'; - import { useI18n } from '/@/hooks/web/useI18n'; - import { useCopyToClipboard } from '/@/hooks/web/useCopyToClipboard'; - import { useMessage } from '/@/hooks/web/useMessage'; + import { useI18n } from '@/hooks/web/useI18n'; import svgIcons from 'virtual:svg-icons-names'; - - // 娌℃湁浣跨敤鍒悕寮曞叆锛屾槸鍥犱负WebStorm褰撳墠鐗堟湰杩樹笉鑳芥纭瘑鍒紝浼氭姤unused璀﹀憡 - const AInput = Input; - const APopover = Popover; - const APagination = Pagination; - const AEmpty = Empty; + import { copyText } from '@/utils/copyTextToClipboard'; function getIcons() { - const data = iconsData as any; - const prefix: string = data?.prefix ?? ''; - let result: string[] = []; - if (prefix) { - result = (data?.icons ?? []).map((item) => `${prefix}:${item}`); - } else if (Array.isArray(iconsData)) { - result = iconsData as string[]; - } - return result; + const prefix = iconsData.prefix; + return iconsData.icons.map((icon) => `${prefix}:${icon}`); } function getSvgIcons() { - return svgIcons.map((icon) => icon.replace('icon-', '')); + return svgIcons.map((icon: string) => icon.replace('icon-', '')); } - const props = defineProps({ - value: propTypes.string, - width: propTypes.string.def('100%'), - pageSize: propTypes.number.def(140), - copy: propTypes.bool.def(false), - mode: propTypes.oneOf<('svg' | 'iconify')[]>(['svg', 'iconify']).def('iconify'), + export interface Props { + value?: string; + width?: string; + pageSize?: number; + copy?: boolean; + mode?: 'svg' | 'iconify'; + allowClear?: boolean; + readonly?: boolean; + } + + const props = withDefaults(defineProps<Props>(), { + value: '', + width: '100%', + pageSize: 140, + copy: false, + mode: 'iconify', + allowClear: true, + readonly: false, + }); + + // Don't inherit FormItem disabled銆乸laceholder... + defineOptions({ + inheritAttrs: false, }); const emit = defineEmits(['change', 'update:value']); @@ -119,22 +131,18 @@ const currentSelect = ref(''); const visible = ref(false); const currentList = ref(icons); + const trigger = ref<HTMLDivElement>(); + + const triggerPopover = () => { + if (trigger.value) { + trigger.value.click(); + } + }; const { t } = useI18n(); const { prefixCls } = useDesign('icon-picker'); const debounceHandleSearchChange = useDebounceFn(handleSearchChange, 100); - - let clipboardRef; - let isSuccessRef; - - if (props.copy) { - const clipboard = useCopyToClipboard(props.value); - clipboardRef = clipboard?.clipboardRef; - isSuccessRef = clipboard?.isSuccessRef; - } - - const { createMessage } = useMessage(); const { getPaginationList, getTotal, setCurrentPage } = usePagination( currentList, @@ -149,10 +157,9 @@ () => currentSelect.value, (v) => { emit('update:value', v); - return emit('change', v); + emit('change', v); }, ); - function handlePageChange(page: number) { setCurrentPage(page); } @@ -160,15 +167,13 @@ function handleClick(icon: string) { currentSelect.value = icon; if (props.copy) { - clipboardRef.value = icon; - if (unref(isSuccessRef)) { - createMessage.success(t('component.icon.copy')); - } + copyText(icon, t('component.icon.copy')); } } function handleSearchChange(e: Event) { - const value = e.target.value; + const value = (e.target as HTMLInputElement).value; + if (!value) { setCurrentPage(1); currentList.value = icons; @@ -185,6 +190,10 @@ padding: 0; } + .ant-input { + cursor: pointer; + } + &-popover { width: 300px; -- Gitblit v1.9.3