feat: Optimize App Store Tag Selection (#10047)

This commit is contained in:
CityFun 2025-08-19 13:43:15 +08:00 committed by GitHub
parent 0dca3fc997
commit e9b4ff1932
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 78 additions and 30 deletions

View file

@ -258,13 +258,13 @@ onMounted(async () => {
padding-bottom: 10px; padding-bottom: 10px;
} }
.tag-button { // .tag-button {
margin-right: 10px; // margin-right: 10px;
&.no-active { // &.no-active {
background: none; // background: none;
border: none; // border: none;
} // }
} // }
@media only screen and (min-width: 768px) and (max-width: 1200px) { @media only screen and (min-width: 768px) and (max-width: 1200px) {
.app-col-12 { .app-col-12 {

View file

@ -1,26 +1,17 @@
<template> <template>
<div> <div ref="containerRef" class="flex gap-2">
<el-button <el-check-tag :checked="activeTag == 'all'" @click="changeTag('all')">
class="tag-button"
:class="activeTag === 'all' ? '' : 'no-active'"
@click="changeTag('all')"
:type="activeTag === 'all' ? 'primary' : ''"
:plain="activeTag !== 'all'"
>
{{ $t('app.all') }} {{ $t('app.all') }}
</el-button> </el-check-tag>
<div v-for="item in tags.slice(0, 7)" :key="item.key" class="inline"> <el-check-tag
<el-button :checked="activeTag == item.key"
class="tag-button" v-for="item in visibleTags"
:class="activeTag === item.key ? '' : 'no-active'" :key="item.key"
@click="changeTag(item.key)" @click="changeTag(item.key)"
:type="activeTag === item.key ? 'primary' : ''" >
:plain="activeTag !== item.key" {{ item.name }}
> </el-check-tag>
{{ item.name }} <div class="inline" v-if="hiddenTags.length > 0">
</el-button>
</div>
<div class="inline">
<el-dropdown> <el-dropdown>
<el-button <el-button
class="tag-button" class="tag-button"
@ -34,7 +25,7 @@
</el-button> </el-button>
<template #dropdown> <template #dropdown>
<el-dropdown-menu> <el-dropdown-menu>
<el-dropdown-item v-for="item in tags.slice(7)" @click="changeTag(item.key)" :key="item.key"> <el-dropdown-item v-for="item in hiddenTags" @click="changeTag(item.key)" :key="item.key">
{{ item.name }} {{ item.name }}
</el-dropdown-item> </el-dropdown-item>
</el-dropdown-menu> </el-dropdown-menu>
@ -55,11 +46,16 @@ const props = defineProps({
}, },
}); });
const containerRef = ref<HTMLElement>();
const activeTag = ref('all'); const activeTag = ref('all');
const tags = ref<App.Tag[]>([]); const tags = ref<App.Tag[]>([]);
const moreTag = ref(''); const moreTag = ref('');
const visibleTagCount = ref(7);
const emit = defineEmits(['change']); const emit = defineEmits(['change']);
const visibleTags = computed(() => tags.value.slice(0, visibleTagCount.value));
const hiddenTags = computed(() => tags.value.slice(visibleTagCount.value));
const getTagValue = (key: string) => { const getTagValue = (key: string) => {
const tag = tags.value.find((tag) => tag.key === key); const tag = tags.value.find((tag) => tag.key === key);
if (tag) { if (tag) {
@ -71,13 +67,47 @@ const changeTag = (key: string) => {
activeTag.value = key; activeTag.value = key;
emit('change', key); emit('change', key);
const index = tags.value.findIndex((tag) => tag.key === key); const index = tags.value.findIndex((tag) => tag.key === key);
if (index > 6) { if (index >= visibleTagCount.value) {
moreTag.value = key; moreTag.value = key;
} else { } else {
moreTag.value = ''; moreTag.value = '';
} }
}; };
const calculateVisibleTagCount = () => {
if (!containerRef.value) return;
const containerWidth = containerRef.value.offsetWidth;
if (containerWidth >= 1800) {
visibleTagCount.value = 18;
} else if (containerWidth >= 1400) {
visibleTagCount.value = 15;
} else if (containerWidth >= 1200) {
visibleTagCount.value = 12;
} else if (containerWidth >= 992) {
visibleTagCount.value = 8;
} else if (containerWidth >= 768) {
visibleTagCount.value = 6;
} else if (containerWidth >= 576) {
visibleTagCount.value = 4;
} else {
visibleTagCount.value = 2;
}
};
let resizeObserver: ResizeObserver | null = null;
const initResizeObserver = () => {
if (!containerRef.value) return;
resizeObserver = new ResizeObserver(() => {
calculateVisibleTagCount();
});
resizeObserver.observe(containerRef.value);
};
const getTags = async () => { const getTags = async () => {
await getAppTags().then((res) => { await getAppTags().then((res) => {
for (let i = 0; i < res.data.length; i++) { for (let i = 0; i < res.data.length; i++) {
@ -87,10 +117,28 @@ const getTags = async () => {
} }
} }
tags.value = res.data; tags.value = res.data;
nextTick(() => {
calculateVisibleTagCount();
});
}); });
}; };
onMounted(() => { onMounted(() => {
getTags(); getTags();
nextTick(() => {
initResizeObserver();
});
});
onBeforeUnmount(() => {
if (resizeObserver) {
resizeObserver.disconnect();
}
}); });
</script> </script>
<style lang="scss" scoped>
.el-check-tag.el-check-tag--primary.is-checked {
background-color: var(--el-color-info-light-9) !important;
}
</style>