fix: 分类页顶部穿透 + 筛选条收起为「几个选中 + 全部类型」

- navbar 背景由半透明渐变(rgba 0.55~0.92)改为实色不透明渐变(#0B0F0E→#0E1412),杜绝 sticky 滚动时内容透视
- filter-bar 内联取消横滑铺全部:收起态只展示最多 3 个选中 chip + 末尾『全部类型』按钮,点击才展开面板陈列全部(选中置顶)
- 单选点已选 chip 打开面板切换;多选点已选 chip 直接移除;超出 3 个显示 +N
This commit is contained in:
2026-07-26 13:10:42 +08:00
parent b6e2093c82
commit 2117225cbb
4 changed files with 29 additions and 37 deletions

View File

@@ -13,9 +13,8 @@ Component({
data: {
panelOpen: false,
panelItems: [], // 选中置顶后的全量列表(供面板渲染)
visibleTags: [], // 多选模式下内联展示的已选标签(上限若干
moreCount: 0, // 多选模式下内联未展示完的已选数量
summary: '' // 单模式下内联展示的当前选中文案
visibleItems: [], // 内联收起态展示的「几个」选中项(单选最多 1多选最多 3
moreCount: 0 // 多选超出展示上限的剩余数量(内联 +N
},
observers: {
@@ -26,46 +25,34 @@ Component({
methods: {
recompute(items) {
// 选中置顶active 的排前面,其余保持原序
// 选中置顶active 的排前面,其余保持原序(面板展开后选中即在最前)
const list = items.slice().sort((a, b) => (b.active ? 1 : 0) - (a.active ? 1 : 0));
if (this.data.multiple) {
const sel = list.filter((i) => i.active);
const MAX = 4;
this.setData({
panelItems: list,
visibleTags: sel.slice(0, MAX),
moreCount: Math.max(0, sel.length - MAX),
summary: ''
});
} else {
const active = list.find((i) => i.active);
this.setData({
panelItems: list,
summary: active ? active.label : (this.data.placeholder || '全部'),
visibleTags: []
});
}
const sel = list.filter((i) => i.active);
const MAX = 3; // 收起态最多展示几个选中项
this.setData({
panelItems: list,
visibleItems: sel.slice(0, MAX),
moreCount: Math.max(0, sel.length - MAX)
});
},
togglePanel() {
this.setData({ panelOpen: !this.data.panelOpen });
},
// 内联一行 chips单选直接选中并回传多选切换 active 并回传全量 values
onChipTap(e) {
// 内联收起态:只展示「几个」选中 chip + 末尾的「全部类型」按钮,不做横滑铺全部
// 单选:点已选 chip 打开面板切换;多选:点已选 chip 直接移除
onChipTapInline(e) {
const value = e.currentTarget.dataset.value;
if (this.data.multiple) {
const next = this.data.items.map((i) =>
i.value === value ? { ...i, active: !i.active } : i
i.value === value ? { ...i, active: false } : i
);
this.recompute(next);
const vals = next.filter((i) => i.active).map((i) => i.value);
this.triggerEvent('change', { values: vals });
} else {
const cur = this.data.items.find((i) => i.value === value);
if (cur && cur.active) return; // 已是当前选中,避免重复触发
this.recompute(this.data.items.map((i) => ({ ...i, active: i.value === value })));
this.triggerEvent('change', { value });
this.togglePanel();
}
},
closePanel() {

View File

@@ -1,17 +1,19 @@
<view class="fb">
<!-- 内联触发条:默认展示一行可横滑的分类 chips,末尾「全部类型」入口 -->
<scroll-view scroll-x class="fb-row" wx:if="{{items.length}}">
<!-- 内联收起态:只展示「几个」选中 chip单选 1 个 / 多选最多 3 个),末尾一个「全部类型」按钮;
点击按钮才展开面板陈列全部,选中项自动置顶。不做横滑铺全部。 -->
<view class="fb-row" wx:if="{{items.length}}">
<view
wx:for="{{items}}"
wx:for="{{visibleItems}}"
wx:key="value"
class="fb-chip {{item.active ? 'fb-chip--active' : ''}}"
data-value="{{item.value}}"
catchtap="onChipTap">{{item.label}}</view>
catchtap="onChipTapInline">{{item.label}}</view>
<view wx:if="{{moreCount > 0}}" class="fb-chip fb-chip--more" catchtap="togglePanel">+{{moreCount}}</view>
<view class="fb-chip fb-chip--all" catchtap="togglePanel">
<text>全部类型</text>
<text>{{visibleItems.length ? '全部类型' : (placeholder || '全部类型')}}</text>
<fc-icon name="chevron-down" size="20" color="var(--text-2)" />
</view>
</scroll-view>
</view>
<!-- 下拉面板:底部弹出,全部分类以网格呈现,选中项自动置顶 -->
<view wx:if="{{panelOpen}}" class="fb-mask" bindtap="closePanel">

View File

@@ -1,8 +1,11 @@
.fb { width: 100%; background: var(--surface); }
/* —— 内联一行可横滑的分类 chips —— */
/* —— 内联收起态:几个选中 chip + 全部类型按钮,单行不横滑 —— */
.fb-row {
white-space: nowrap;
display: flex;
align-items: center;
flex-wrap: nowrap;
overflow: hidden;
padding: 4rpx 4rpx 8rpx;
background: var(--surface);
}

View File

@@ -1,5 +1,5 @@
.navbar {
background: linear-gradient(180deg, var(--bar-bg) 0%, var(--float-bg) 100%);
background: linear-gradient(180deg, #0B0F0E 0%, #0E1412 100%);
position: sticky;
top: 0;
z-index: 50;