实现ui问题
This commit is contained in:
@@ -58,6 +58,8 @@ buildUrl(ASSET_BASE + 'logo.png')
|
||||
| PingFang SC/ 文件夹(7 个字重 ttf,见 2.3) | fonts/PingFang-Regular.subset.ttf 等(已生成,见 2.3) | 全局字体 |
|
||||
|
||||
> 中文文件名由 buildUrl/uni.request 自动 URL 编码,三端均可正常访问;只有字体目录用英文名 `fonts/`。
|
||||
>
|
||||
> Figma 导出的小图标(UI-009/0010)为本地静态资源,不上传服务器:`static/icons/products/icon_search.png`(48×48@3x)、`static/icons/products/icon_filter.png`(54×54@3x)。
|
||||
|
||||
### 2.3 字体方案
|
||||
|
||||
@@ -213,14 +215,16 @@ uni.loadFontFace({
|
||||
### UI-009 产品页 · 搜索栏 · 图标与搜索按钮(P1)
|
||||
|
||||
- 文件:[SearchBar.vue](pages/products/components/SearchBar.vue)
|
||||
- 方案:
|
||||
1. 替换现有搜索图标为设计稿图标(**注意:切图文件夹内暂无搜索图标,需向设计索取或从设计稿导出**)
|
||||
2. 搜索框右侧增加"搜索"按钮,样式按设计稿
|
||||
- 方案(按 Figma node-id=1962-143):
|
||||
1. emoji 🔍 替换为设计稿导出的 `icon_search.png`(31rpx,Figma 3 倍图 48×48)
|
||||
2. 搜索框右侧增加"搜索"按钮:96×54rpx、`#FF6800`、圆角 27rpx、白字 25rpx,距框边缘 4rpx,点击触发搜索
|
||||
3. 搜索框 209×32px → 402×62rpx,`#F5F5F5` 圆角 31rpx;占位文案"搜索产品" `#929292` 25rpx;上下留白 6px→12rpx
|
||||
|
||||
### UI-0010 产品页 · 搜索栏 · 筛选被遮挡(P1)
|
||||
|
||||
- 文件:[SearchBar.vue](pages/products/components/SearchBar.vue) / [products.vue](pages/products/products.vue)
|
||||
- 方案:参考设计稿调整搜索栏与筛选按钮布局(层级/宽度/间距),确保筛选按钮完整可见可点
|
||||
- 文件:[SearchBar.vue](pages/products/components/SearchBar.vue) / [products.vue](pages/products/products.vue) / [products.css](pages/products/products.css)
|
||||
- 被遮挡原因:筛选按钮原在搜索行右侧,小程序胶囊按钮恰好覆盖该区域
|
||||
- 方案(按设计稿+实际确认):筛选入口与已选标签合并为**同一行**([ActiveFilters.vue](pages/products/components/ActiveFilters.vue) 重构):`[筛选图标 35rpx] [已选标签 scroll-x 横向滚动不换行] [清除(有标签才显示)]`;搜索行右侧留空避开胶囊;FilterDrawer 弹窗逻辑不变(入口 emit `open` → 父组件 `toggleFilter`)
|
||||
|
||||
### UI-0011 产品页 · 国家分类 · 间距(P3)
|
||||
|
||||
@@ -270,8 +274,8 @@ uni.loadFontFace({
|
||||
| UI-006 | ✅ 已改 | [WhyChoose.vue](pages/index/components/WhyChoose.vue):标题"为什么选择Inkrecah?"→"为什么选择Inkreach?";卡片去掉 margin-bottom,上下间距统一用 gap 20rpx 与左右一致;区块上下留白对称(96rpx) |
|
||||
| UI-007 | ✅ 已改 | [CompanyIntro.vue](pages/index/components/CompanyIntro.vue) 背景图改用远程切图原图 公司简介背景.png |
|
||||
| UI-008 | ✅ 已改 | CompanyIntro.vue `.phone-text` 字号 23rpx → 31rpx(16号) |
|
||||
| UI-009 | ⏸ 暂缓 | 等设计/Figma(node-id=1962-143) |
|
||||
| UI-0010 | ⏸ 暂缓 | 等设计/Figma(node-id=1962-143) |
|
||||
| UI-009 | ✅ 已改 | [SearchBar.vue](pages/products/components/SearchBar.vue):emoji 🔍 → Figma 导出 icon_search.png(31rpx);新增橙色"搜索"按钮(96×54rpx `#FF6800` 圆角 27rpx,点击/键盘确认均触发搜索);搜索框 402×62rpx `#F5F5F5` 圆角 31rpx,占位"搜索产品" 25rpx `#929292` |
|
||||
| UI-0010 | ✅ 已改 | 筛选入口从搜索行(被胶囊遮挡)移至商品区顶部;[ActiveFilters.vue](pages/products/components/ActiveFilters.vue) 重构为一行布局:筛选图标 + 已选标签横向滚动(scroll-x 不换行)+ 清除按钮,FilterDrawer 逻辑不变 |
|
||||
| UI-0011 | ✅ 已改 | [CountryBar.vue](pages/products/components/CountryBar.vue):国旗与名称间距 20rpx → 8rpx(4px);标签上下 row-gap 16rpx → 20rpx(+2px) |
|
||||
| UI-0012 | ✅ 已改 | [products.css](pages/products/products.css) 页面背景 + [ProductGrid.vue](pages/products/components/ProductGrid.vue) 右侧内容区背景 → #ECECEC |
|
||||
| UI-0013 | ✅ 已改 | tab_product_gray/orange.png 由 57×57 放大至 72×72(Pillow LANCZOS),与 home 图标一致 |
|
||||
|
||||
@@ -1,11 +1,27 @@
|
||||
<template>
|
||||
<!-- 已选筛选标签 - Figma 1519:250 圆角 60px -->
|
||||
<view class="active-filters" id="activeFilters" v-if="list.length > 0">
|
||||
<view class="active-filter-tag" v-for="(item, index) in list" :key="index">
|
||||
<text class="filter-text">{{ item.label }}</text>
|
||||
<text class="filter-remove" @tap="onRemove(item.key)">×</text>
|
||||
<!-- 筛选条件条:[筛选图标] [已选标签横向滚动] [清除] 同一行,防换行 -->
|
||||
<view class="active-filters" id="activeFilters">
|
||||
<!-- 筛选入口:打开筛选抽屉 -->
|
||||
<view class="filter-entry" @tap="onOpen">
|
||||
<image
|
||||
class="filter-entry-icon"
|
||||
src="/static/icons/products/icon_filter.png"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
</view>
|
||||
<view class="clear-all" @tap="onClearAll">清除全部</view>
|
||||
|
||||
<!-- 已选标签:横向滚动,不换行 -->
|
||||
<scroll-view class="tags-scroll" scroll-x>
|
||||
<view class="tags-inner">
|
||||
<view class="active-filter-tag" v-for="(item, index) in list" :key="index">
|
||||
<text class="filter-text">{{ item.label }}</text>
|
||||
<text class="filter-remove" @tap="onRemove(item.key)">×</text>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
<!-- 清除:有标签时才显示 -->
|
||||
<view class="clear-all" v-if="list.length > 0" @tap="onClearAll">清除</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
@@ -19,7 +35,7 @@ export default {
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
// 首次测量(可能为 0,因为 v-if 可能为 false)
|
||||
// 首次测量自身高度给父组件布局用
|
||||
this.$nextTick(() => this.emitHeight())
|
||||
},
|
||||
watch: {
|
||||
@@ -30,11 +46,6 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
emitHeight() {
|
||||
// v-if 为 false 时 #activeFilters 不存在,返回 0
|
||||
if (!this.list || this.list.length === 0) {
|
||||
this.$emit('height-change', 0)
|
||||
return
|
||||
}
|
||||
const query = uni.createSelectorQuery().in(this)
|
||||
query.select('#activeFilters').boundingClientRect()
|
||||
query.exec((res) => {
|
||||
@@ -45,6 +56,9 @@ export default {
|
||||
}
|
||||
})
|
||||
},
|
||||
onOpen() {
|
||||
this.$emit('open')
|
||||
},
|
||||
onRemove(key) {
|
||||
this.$emit('remove', key)
|
||||
},
|
||||
@@ -56,26 +70,48 @@ export default {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 顶部筛选条 - 白底,不占高度时隐藏 */
|
||||
/* 顶部筛选条 - 白底,筛选图标 + 横向滚动标签 + 清除,同一行 */
|
||||
.active-filters {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 16rpx;
|
||||
padding: 20rpx 20rpx;
|
||||
padding: 16rpx 20rpx;
|
||||
background: #ffffff;
|
||||
border-bottom: 1rpx solid #eeeeee;
|
||||
}
|
||||
/* 单个标签 - padding 6px 10px 圆角 60px */
|
||||
.active-filter-tag {
|
||||
/* 筛选入口图标(设计稿 18x18px → 35rpx) */
|
||||
.filter-entry {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 8rpx 16rpx 8rpx 0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.filter-entry-icon {
|
||||
width: 35rpx;
|
||||
height: 35rpx;
|
||||
}
|
||||
/* 标签区:横向滚动不换行 */
|
||||
.tags-scroll {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.tags-inner {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 16rpx;
|
||||
padding: 4rpx 0;
|
||||
}
|
||||
/* 单个标签 - padding 6px 10px 圆角 60px,不换行 */
|
||||
.active-filter-tag {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8rpx;
|
||||
padding: 12rpx 20rpx;
|
||||
background: #ffffff;
|
||||
border: 1rpx solid #ff6800;
|
||||
border-radius: 60rpx;
|
||||
line-height: 1.2;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
/* 文字 12px Medium 橙色 */
|
||||
.filter-text {
|
||||
@@ -88,7 +124,8 @@ export default {
|
||||
color: #ff6800;
|
||||
}
|
||||
.clear-all {
|
||||
margin-left: auto;
|
||||
padding-left: 16rpx;
|
||||
flex-shrink: 0;
|
||||
font-size: 24rpx;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
@@ -2,19 +2,17 @@
|
||||
<!-- 搜索栏 -->
|
||||
<view class="search-bar" id="searchBar" :style="{ paddingTop: statusBarHeight + 'px' }">
|
||||
<view class="search-input-wrap">
|
||||
<text class="search-icon">🔍</text>
|
||||
<image class="search-icon" src="/static/icons/products/icon_search.png" mode="aspectFit" />
|
||||
<input
|
||||
class="search-input"
|
||||
placeholder="搜索商品"
|
||||
placeholder="搜索产品"
|
||||
placeholder-class="search-placeholder"
|
||||
:value="keyword"
|
||||
@input="onInput"
|
||||
@blur="onBlur"
|
||||
@confirm="onConfirm"
|
||||
/>
|
||||
</view>
|
||||
<view class="filter-btn" @tap="onFilter">
|
||||
<text class="filter-icon">⚙</text>
|
||||
<text class="filter-text">筛选</text>
|
||||
<view class="search-btn" @tap="onSearch">搜索</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
@@ -61,56 +59,60 @@ export default {
|
||||
onBlur() {
|
||||
this.$emit('blur')
|
||||
},
|
||||
onFilter() {
|
||||
this.$emit('filter')
|
||||
onConfirm() {
|
||||
// 键盘确认键与搜索按钮同一行为
|
||||
this.$emit('blur')
|
||||
},
|
||||
onSearch() {
|
||||
this.$emit('search')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 设计稿:左右留白 10px(20rpx),上下留白 6px(12rpx),搜索框 209x32px(402x62rpx) */
|
||||
.search-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 20rpx;
|
||||
padding: 20rpx 32rpx;
|
||||
padding: 12rpx 20rpx;
|
||||
background: #ffffff;
|
||||
border-bottom: 2rpx solid #f5f5f5;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.search-input-wrap {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 72rpx;
|
||||
padding: 0 24rpx;
|
||||
width: 402rpx;
|
||||
height: 62rpx;
|
||||
padding: 0 4rpx 0 21rpx;
|
||||
background: #f5f5f5;
|
||||
border-radius: 36rpx;
|
||||
border-radius: 31rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.search-icon {
|
||||
font-size: 28rpx;
|
||||
margin-right: 12rpx;
|
||||
width: 31rpx;
|
||||
height: 31rpx;
|
||||
flex-shrink: 0;
|
||||
margin-right: 8rpx;
|
||||
}
|
||||
.search-input {
|
||||
flex: 1;
|
||||
font-size: 26rpx;
|
||||
min-width: 0;
|
||||
font-size: 25rpx;
|
||||
color: #333333;
|
||||
}
|
||||
.search-placeholder {
|
||||
color: #999999;
|
||||
color: #929292;
|
||||
}
|
||||
.filter-btn {
|
||||
/* 设计稿:搜索按钮 50x28px(96x54rpx),#FF6800,圆角 14px(27rpx),距边缘 2px(4rpx) */
|
||||
.search-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8rpx;
|
||||
padding: 12rpx 20rpx;
|
||||
font-size: 26rpx;
|
||||
color: #666666;
|
||||
}
|
||||
.filter-icon {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
.filter-text {
|
||||
font-size: 26rpx;
|
||||
justify-content: center;
|
||||
width: 96rpx;
|
||||
height: 54rpx;
|
||||
flex-shrink: 0;
|
||||
background: #ff6800;
|
||||
border-radius: 27rpx;
|
||||
font-size: 25rpx;
|
||||
color: #ffffff;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
:keyword="searchKeyword"
|
||||
@input="onSearchInput"
|
||||
@blur="onSearchBlur"
|
||||
@filter="toggleFilter"
|
||||
@search="onSearchBlur"
|
||||
@height-change="onSearchBarHeight"
|
||||
/>
|
||||
|
||||
@@ -29,9 +29,10 @@
|
||||
|
||||
<!-- 右侧内容区:上方筛选条件 + 下方商品滚动区 -->
|
||||
<view class="right-wrap">
|
||||
<!-- 已选筛选标签(只在右侧顶部出现,不挤压左边) -->
|
||||
<!-- 筛选条件条:筛选图标 + 已选标签横向滚动 + 清除,同一行 -->
|
||||
<ActiveFilters
|
||||
:list="activeFilters"
|
||||
@open="toggleFilter"
|
||||
@remove="removeFilter"
|
||||
@clear-all="clearAllFilters"
|
||||
@height-change="onActiveFiltersHeight"
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 268 B |
Binary file not shown.
|
After Width: | Height: | Size: 661 B |
Reference in New Issue
Block a user