优化 PC 首页点击式筛选与排序体验
默认区平铺常用条件并支持刀皮/红皮/枪皮多选,高级筛选折叠展示;修复综合推荐无法选中、筛选排序导致页面回顶等问题。
This commit is contained in:
@@ -39,20 +39,26 @@ const announcements = ref<string[]>(defaultHomeAnnouncements)
|
||||
const banners = ref<HomeBannerSlide[]>(defaultHomeBanners)
|
||||
const publishOptions = ref<ListingPublishOptions>(emptyListingPublishOptions)
|
||||
const sortBy = ref('recommended')
|
||||
const sortOptions = [
|
||||
{ value: 'recommended', label: '综合推荐' },
|
||||
{ value: 'coinDesc', label: '哈夫币' },
|
||||
{ value: 'awmDesc', label: 'AWM数量' },
|
||||
{ value: 'priceAsc', label: '价格最低' },
|
||||
{ value: 'priceDesc', label: '价格最高' },
|
||||
] as const
|
||||
const activeZone = ref('all')
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
|
||||
const {
|
||||
filters,
|
||||
activeFilterPopover,
|
||||
regionOptions,
|
||||
loginMethodOptions,
|
||||
skinFilterGroups,
|
||||
skinChipLabel,
|
||||
advancedSkinFilterGroups,
|
||||
advancedFiltersOpen,
|
||||
advancedActiveCount,
|
||||
resetFilters,
|
||||
setFilterPopover,
|
||||
closeFilterPopover,
|
||||
} = useHomeFilters(
|
||||
publishOptions,
|
||||
computed(() => listings.value)
|
||||
@@ -167,9 +173,10 @@ function handleResetFilters() {
|
||||
|
||||
function applyRouteQueryToHomeState() {
|
||||
const storedQuery = readStoredHomeQuery(desktopHomeFilterStorageKey)
|
||||
const query = hasHomeQueryValues(route.query, desktopHomeFilterQueryKeys)
|
||||
? route.query
|
||||
: storedQuery
|
||||
const routeHasManaged = hasHomeQueryValues(route.query, desktopHomeFilterQueryKeys)
|
||||
// 路由有托管参数时以路由为准;否则回退 session。
|
||||
// 注意:综合推荐时 sort 不在 URL,若路由仍有其它筛选参数,也不要用 storage 覆盖 sort。
|
||||
const query = routeHasManaged ? route.query : storedQuery
|
||||
filters.keyword = readQueryString(query, 'keyword')
|
||||
filters.server = readQueryString(query, 'server')
|
||||
filters.region = readQueryCSV(query, 'region')
|
||||
@@ -178,8 +185,8 @@ function applyRouteQueryToHomeState() {
|
||||
filters.insurance = readQueryCSV(query, 'insurance')
|
||||
filters.stamina = readQueryCSV(query, 'stamina')
|
||||
filters.load = readQueryCSV(query, 'load')
|
||||
filters.skinGroup = readQueryString(query, 'skin_group')
|
||||
filters.skinName = readQueryString(query, 'skin_name')
|
||||
// 兼容旧单值 skin_name / 新 CSV 多选
|
||||
filters.skinNames = readQueryCSV(query, 'skin_name')
|
||||
filters.minCoin = readQueryNumber(query, 'min_coin')
|
||||
filters.maxCoin = readQueryNumber(query, 'max_coin')
|
||||
filters.minRatio = readQueryNumber(query, 'min_ratio')
|
||||
@@ -192,6 +199,7 @@ function applyRouteQueryToHomeState() {
|
||||
filters.maxTotal = readQueryNumber(query, 'max_total')
|
||||
filters.minFireLevel = readQueryNumber(query, 'min_fire_level')
|
||||
filters.maxFireLevel = readQueryNumber(query, 'max_fire_level')
|
||||
// 无 sort 参数即综合推荐(默认)
|
||||
sortBy.value = readQueryString(query, 'sort') || 'recommended'
|
||||
// zone 不从 query/storage 恢复,由用户实时点击决定,不参与筛选持久化
|
||||
}
|
||||
@@ -206,8 +214,12 @@ function syncHomeQuery() {
|
||||
desktopHomeFilterQueryKeys,
|
||||
buildDesktopHomeQueryValues()
|
||||
)
|
||||
// 综合推荐不写 sort;若当前无任何筛选条件,必须清空 storage,
|
||||
// 否则会回退读到旧的 sort=coinDesc 等,导致无法选回「综合推荐」。
|
||||
if (hasHomeQueryValues(query, desktopHomeFilterQueryKeys)) {
|
||||
storeHomeQuery(desktopHomeFilterStorageKey, query)
|
||||
} else {
|
||||
clearStoredHomeQuery(desktopHomeFilterStorageKey)
|
||||
}
|
||||
if (isSameQuery(route.query, query)) return
|
||||
router.replace({ path: '/', query })
|
||||
@@ -224,8 +236,7 @@ function buildDesktopHomeQueryValues(): Record<string, HomeQueryValue> {
|
||||
insurance: joinQueryCSV(filters.insurance),
|
||||
stamina: joinQueryCSV(filters.stamina),
|
||||
load: joinQueryCSV(filters.load),
|
||||
skin_group: filters.skinGroup || undefined,
|
||||
skin_name: filters.skinName || undefined,
|
||||
skin_name: joinQueryCSV(filters.skinNames),
|
||||
min_coin: filters.minCoin,
|
||||
max_coin: filters.maxCoin,
|
||||
min_ratio: filters.minRatio,
|
||||
@@ -273,12 +284,12 @@ loadHome()
|
||||
:region-options="regionOptions"
|
||||
:login-method-options="loginMethodOptions"
|
||||
:skin-filter-groups="skinFilterGroups"
|
||||
:skin-chip-label="skinChipLabel"
|
||||
:active-filter-popover="activeFilterPopover"
|
||||
:advanced-skin-filter-groups="advancedSkinFilterGroups"
|
||||
:advanced-open="advancedFiltersOpen"
|
||||
:advanced-active-count="advancedActiveCount"
|
||||
@update:filters="updateFilters"
|
||||
@update:advanced-open="advancedFiltersOpen = $event"
|
||||
@reset="handleResetFilters"
|
||||
@set-filter-popover="setFilterPopover"
|
||||
@close-filter-popover="closeFilterPopover"
|
||||
/>
|
||||
|
||||
<div class="list-head">
|
||||
@@ -286,14 +297,17 @@ loadHome()
|
||||
<p class="eyebrow">Account Zone</p>
|
||||
<h2>账号专区</h2>
|
||||
</div>
|
||||
<div class="list-actions">
|
||||
<el-radio-group v-model="sortBy" size="small">
|
||||
<el-radio-button label="recommended">综合推荐</el-radio-button>
|
||||
<el-radio-button label="coinDesc">哈夫币</el-radio-button>
|
||||
<el-radio-button label="awmDesc">AWM数量</el-radio-button>
|
||||
<el-radio-button label="priceAsc">价格最低</el-radio-button>
|
||||
<el-radio-button label="priceDesc">价格最高</el-radio-button>
|
||||
</el-radio-group>
|
||||
<div class="list-actions sort-bar" role="group" aria-label="排序方式">
|
||||
<button
|
||||
v-for="item in sortOptions"
|
||||
:key="item.value"
|
||||
type="button"
|
||||
class="sort-chip"
|
||||
:class="{ active: sortBy === item.value }"
|
||||
@click="sortBy = item.value"
|
||||
>
|
||||
{{ item.label }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -401,6 +415,8 @@ loadHome()
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-end;
|
||||
gap: 16px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.zone-head {
|
||||
@@ -425,6 +441,43 @@ loadHome()
|
||||
color: #17233d;
|
||||
}
|
||||
|
||||
.sort-bar {
|
||||
display: inline-flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
padding: 4px;
|
||||
border-radius: 12px;
|
||||
background: #f3f5f9;
|
||||
}
|
||||
|
||||
.sort-chip {
|
||||
min-height: 32px;
|
||||
padding: 0 14px;
|
||||
border: none;
|
||||
border-radius: 9px;
|
||||
background: transparent;
|
||||
color: #64748b;
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
cursor: pointer;
|
||||
transition:
|
||||
background 0.15s ease,
|
||||
color 0.15s ease,
|
||||
box-shadow 0.15s ease;
|
||||
}
|
||||
|
||||
.sort-chip:hover {
|
||||
color: #334155;
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
|
||||
.sort-chip.active {
|
||||
background: #ffffff;
|
||||
color: #ff6a00;
|
||||
box-shadow: 0 1px 4px rgba(23, 35, 61, 0.08);
|
||||
}
|
||||
|
||||
.enhanced-desktop-list {
|
||||
display: grid;
|
||||
gap: 16px;
|
||||
|
||||
Reference in New Issue
Block a user