hookehuyr

style(material-list): 优化资料列表页和首页样式及交互动效

- 重构资料列表页卡片布局,增加圆角、阴影和渐变色
- 统一收藏按钮尺寸为64rpx并添加点击反馈动画
- 为列表项添加入场动画和收藏状态切换动效
- 首页热门资料列表替换为图标样式,优化文案一致性
## [2026-01-31] - 资料列表页样式优化
### 优化
- 优化资料列表页 (`src/pages/material-list`) 的布局和样式
- 卡片增加圆角、阴影和内边距,提升视觉层次
- 优化列表项布局,改善间距和对齐
- 统一收藏按钮大小为 64rpx,确保点击区域一致性
- 增强交互动效:
- 列表项入场动画(Slide In)
- 收藏按钮点击缩放反馈
- 收藏状态切换颜色过渡
- 使用 Tailwind CSS 和 Less 混合编写样式
---
**详细信息**
- **影响文件**: src/pages/material-list/index.vue
- **技术栈**: Vue 3, Tailwind CSS, Less
- **测试状态**: 已通过
- **备注**:
- 响应用户关于美化页面和统一按钮大小的需求
## [2026-01-31] - 首页资料列表样式优化
### 优化
- 将首页"本周热门资料"列表左边的图片替换为图标样式
- 使用 80rpx × 88rpx 圆角蓝色背景容器(bg-blue-50)
- IconFont 图标尺寸 32,与资料列表页面保持一致
- 不同资料项使用不同颜色图标(红色 #EF4444、蓝色 #3B82F6、绿色 #10B981)
- 优化文案:"热卖产品:" → "热卖产品"(去掉冒号)
- 修正产品按钮文案:"产品资料" → "产品详情"
---
**详细信息**
- **影响文件**: src/pages/index/index.vue
- **技术栈**: Vue 3, Taro 4, NutUI, IconFont
- **测试状态**: 已通过
- **备注**:
- 统一首页与资料列表页的图标样式
- 提升视觉一致性
- 更符合整体设计风格
## [2026-01-31] - 代码注释规范
### 文档
......
......@@ -9,7 +9,7 @@
<!-- Search Bar -->
<div class="px-[32rpx] mt-[32rpx]">
<div class="bg-white rounded-[12rpx] flex items-center px-[32rpx] py-[24rpx]">
<div class="bg-white rounded-[20rpx] flex items-center px-[32rpx] py-[24rpx] shadow-sm border border-gray-50">
<IconFont name="search" size="20" color="#9CA3AF" class="mr-[16rpx]" />
<input v-model="searchValue" type="text" placeholder="搜索资料..."
class="flex-1 text-[28rpx] text-[#1F2937] placeholder-gray-400 bg-transparent outline-none"
......@@ -18,39 +18,52 @@
</div>
<!-- Material List -->
<div class="px-[32rpx] mt-[40rpx]">
<div class="bg-white rounded-[32rpx] p-[32rpx] shadow-sm">
<div v-for="(item, index) in list" :key="index">
<div class="flex justify-between items-start pt-[32rpx] first:pt-0">
<div class="flex items-start flex-1 mr-[20rpx]" @tap="onView(item)">
<div class="px-[32rpx] mt-[32rpx]">
<div class="flex flex-col gap-[24rpx]">
<div v-for="(item, index) in list" :key="index"
class="material-item bg-white rounded-[24rpx] p-[24rpx] shadow-sm flex items-start active:scale-[0.98] transition-all duration-200 border border-gray-50"
:style="{ animationDelay: `${index * 50}ms` }" @click="onView(item)">
<!-- 左侧图标 -->
<div
class="w-[80rpx] h-[88rpx] mr-[24rpx] flex-shrink-0 flex items-center justify-center bg-blue-50 rounded-[12rpx]">
class="w-[88rpx] h-[88rpx] mr-[24rpx] flex-shrink-0 flex items-center justify-center bg-gradient-to-br from-blue-50 to-blue-100 rounded-[20rpx] shadow-inner">
<IconFont :name="item.iconName || 'order'" size="32" :color="item.iconColor || '#2563EB'" />
</div>
<div class="flex flex-col">
<span class="text-[#1F2937] text-[28rpx] font-normal leading-[1.2] mb-[14rpx] line-clamp-2">
<!-- 内容区域 -->
<div class="flex-1 min-w-0">
<div class="flex justify-between items-start gap-[16rpx]">
<div class="flex-1 pr-[8rpx]">
<h3 class="text-[#1F2937] text-[30rpx] font-bold leading-[1.4] line-clamp-2 mb-[8rpx]">
{{ item.title }}
</span>
<span class="text-[#6B7280] text-[24rpx] leading-[1.3] line-clamp-1">
</h3>
<p class="text-[#6B7280] text-[24rpx] leading-[1.4] line-clamp-1 mb-[16rpx]">
{{ item.desc }}
</span>
</p>
</div>
<!-- 收藏图标 -->
<div
class="heart-btn w-[64rpx] h-[64rpx] -mt-[12rpx] -mr-[12rpx] flex items-center justify-center rounded-full active:bg-gray-50 transition-colors"
@click.stop="toggleCollect(item)">
<div :class="{ 'is-collected': item.collected }" class="transform transition-transform duration-300">
<IconFont :name="item.collected ? 'heart-fill' : 'heart'" size="24"
:color="item.collected ? '#EF4444' : '#D1D5DB'" />
</div>
</div>
</div>
<div class="flex items-center mt-[16rpx] ml-[104rpx] pb-[32rpx]">
<span class="text-[#9CA3AF] text-[24rpx] mr-[40rpx]">{{ item.size }}</span>
<div class="flex items-center" @click="toggleCollect(item)">
<IconFont :name="item.collected ? 'StarFill' : 'Star'" size="12"
:color="item.collected ? '#F59E0B' : '#9CA3AF'" class="mr-[8rpx]" />
<span :class="['text-[24rpx]', item.collected ? 'text-[#F59E0B]' : 'text-[#9CA3AF]']">
{{ item.collected ? '已收藏' : '收藏' }}
<!-- 底部信息:文件大小 -->
<div class="flex items-center gap-[12rpx]">
<span
class="inline-flex items-center justify-center px-[12rpx] py-[4rpx] bg-gray-100 text-gray-500 text-[20rpx] font-medium rounded-[8rpx]">
PDF
</span>
<span class="text-[#9CA3AF] text-[22rpx]">
{{ item.size }}
</span>
</div>
</div>
<!-- Divider -->
<div v-if="index < list.length - 1" class="h-[1px] bg-[#E5E7EB] w-full mb-[32rpx]"></div>
</div>
</div>
</div>
......@@ -335,3 +348,48 @@ const onView = (item) => {
downloadAndOpenFile(item)
}
</script>
<style lang="less" scoped>
@keyframes slideIn {
from {
opacity: 0;
transform: translateY(20rpx);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.material-item {
animation: slideIn 0.5s cubic-bezier(0.2, 0.8, 0.2, 1) backwards;
}
/* 收藏成功的动画 */
.is-collected {
animation: heartBeat 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
@keyframes heartBeat {
0% {
transform: scale(1);
}
14% {
transform: scale(1.3);
}
28% {
transform: scale(1);
}
42% {
transform: scale(1.3);
}
70% {
transform: scale(1);
}
}
</style>
......