hookehuyr

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

- 重构资料列表页卡片布局,增加圆角、阴影和渐变色
- 统一收藏按钮尺寸为64rpx并添加点击反馈动画
- 为列表项添加入场动画和收藏状态切换动效
- 首页热门资料列表替换为图标样式,优化文案一致性
1 +## [2026-01-31] - 资料列表页样式优化
2 +
3 +### 优化
4 +- 优化资料列表页 (`src/pages/material-list`) 的布局和样式
5 + - 卡片增加圆角、阴影和内边距,提升视觉层次
6 + - 优化列表项布局,改善间距和对齐
7 + - 统一收藏按钮大小为 64rpx,确保点击区域一致性
8 + - 增强交互动效:
9 + - 列表项入场动画(Slide In)
10 + - 收藏按钮点击缩放反馈
11 + - 收藏状态切换颜色过渡
12 + - 使用 Tailwind CSS 和 Less 混合编写样式
13 +
14 +---
15 +
16 +**详细信息**
17 +- **影响文件**: src/pages/material-list/index.vue
18 +- **技术栈**: Vue 3, Tailwind CSS, Less
19 +- **测试状态**: 已通过
20 +- **备注**:
21 + - 响应用户关于美化页面和统一按钮大小的需求
22 +
23 +## [2026-01-31] - 首页资料列表样式优化
24 +
25 +### 优化
26 +- 将首页"本周热门资料"列表左边的图片替换为图标样式
27 + - 使用 80rpx × 88rpx 圆角蓝色背景容器(bg-blue-50)
28 + - IconFont 图标尺寸 32,与资料列表页面保持一致
29 + - 不同资料项使用不同颜色图标(红色 #EF4444、蓝色 #3B82F6、绿色 #10B981)
30 +- 优化文案:"热卖产品:" → "热卖产品"(去掉冒号)
31 +- 修正产品按钮文案:"产品资料" → "产品详情"
32 +
33 +---
34 +
35 +**详细信息**
36 +- **影响文件**: src/pages/index/index.vue
37 +- **技术栈**: Vue 3, Taro 4, NutUI, IconFont
38 +- **测试状态**: 已通过
39 +- **备注**:
40 + - 统一首页与资料列表页的图标样式
41 + - 提升视觉一致性
42 + - 更符合整体设计风格
43 +
1 ## [2026-01-31] - 代码注释规范 44 ## [2026-01-31] - 代码注释规范
2 45
3 ### 文档 46 ### 文档
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
9 9
10 <!-- Search Bar --> 10 <!-- Search Bar -->
11 <div class="px-[32rpx] mt-[32rpx]"> 11 <div class="px-[32rpx] mt-[32rpx]">
12 - <div class="bg-white rounded-[12rpx] flex items-center px-[32rpx] py-[24rpx]"> 12 + <div class="bg-white rounded-[20rpx] flex items-center px-[32rpx] py-[24rpx] shadow-sm border border-gray-50">
13 <IconFont name="search" size="20" color="#9CA3AF" class="mr-[16rpx]" /> 13 <IconFont name="search" size="20" color="#9CA3AF" class="mr-[16rpx]" />
14 <input v-model="searchValue" type="text" placeholder="搜索资料..." 14 <input v-model="searchValue" type="text" placeholder="搜索资料..."
15 class="flex-1 text-[28rpx] text-[#1F2937] placeholder-gray-400 bg-transparent outline-none" 15 class="flex-1 text-[28rpx] text-[#1F2937] placeholder-gray-400 bg-transparent outline-none"
...@@ -18,39 +18,52 @@ ...@@ -18,39 +18,52 @@
18 </div> 18 </div>
19 19
20 <!-- Material List --> 20 <!-- Material List -->
21 - <div class="px-[32rpx] mt-[40rpx]"> 21 + <div class="px-[32rpx] mt-[32rpx]">
22 - <div class="bg-white rounded-[32rpx] p-[32rpx] shadow-sm"> 22 + <div class="flex flex-col gap-[24rpx]">
23 - <div v-for="(item, index) in list" :key="index"> 23 + <div v-for="(item, index) in list" :key="index"
24 - <div class="flex justify-between items-start pt-[32rpx] first:pt-0"> 24 + 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"
25 - <div class="flex items-start flex-1 mr-[20rpx]" @tap="onView(item)"> 25 + :style="{ animationDelay: `${index * 50}ms` }" @click="onView(item)">
26 +
27 + <!-- 左侧图标 -->
26 <div 28 <div
27 - class="w-[80rpx] h-[88rpx] mr-[24rpx] flex-shrink-0 flex items-center justify-center bg-blue-50 rounded-[12rpx]"> 29 + 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">
28 <IconFont :name="item.iconName || 'order'" size="32" :color="item.iconColor || '#2563EB'" /> 30 <IconFont :name="item.iconName || 'order'" size="32" :color="item.iconColor || '#2563EB'" />
29 </div> 31 </div>
30 - <div class="flex flex-col"> 32 +
31 - <span class="text-[#1F2937] text-[28rpx] font-normal leading-[1.2] mb-[14rpx] line-clamp-2"> 33 + <!-- 内容区域 -->
34 + <div class="flex-1 min-w-0">
35 + <div class="flex justify-between items-start gap-[16rpx]">
36 + <div class="flex-1 pr-[8rpx]">
37 + <h3 class="text-[#1F2937] text-[30rpx] font-bold leading-[1.4] line-clamp-2 mb-[8rpx]">
32 {{ item.title }} 38 {{ item.title }}
33 - </span> 39 + </h3>
34 - <span class="text-[#6B7280] text-[24rpx] leading-[1.3] line-clamp-1"> 40 + <p class="text-[#6B7280] text-[24rpx] leading-[1.4] line-clamp-1 mb-[16rpx]">
35 {{ item.desc }} 41 {{ item.desc }}
36 - </span> 42 + </p>
43 + </div>
44 +
45 + <!-- 收藏图标 -->
46 + <div
47 + class="heart-btn w-[64rpx] h-[64rpx] -mt-[12rpx] -mr-[12rpx] flex items-center justify-center rounded-full active:bg-gray-50 transition-colors"
48 + @click.stop="toggleCollect(item)">
49 + <div :class="{ 'is-collected': item.collected }" class="transform transition-transform duration-300">
50 + <IconFont :name="item.collected ? 'heart-fill' : 'heart'" size="24"
51 + :color="item.collected ? '#EF4444' : '#D1D5DB'" />
37 </div> 52 </div>
38 </div> 53 </div>
39 </div> 54 </div>
40 55
41 - <div class="flex items-center mt-[16rpx] ml-[104rpx] pb-[32rpx]"> 56 + <!-- 底部信息:文件大小 -->
42 - <span class="text-[#9CA3AF] text-[24rpx] mr-[40rpx]">{{ item.size }}</span> 57 + <div class="flex items-center gap-[12rpx]">
43 - <div class="flex items-center" @click="toggleCollect(item)"> 58 + <span
44 - <IconFont :name="item.collected ? 'StarFill' : 'Star'" size="12" 59 + class="inline-flex items-center justify-center px-[12rpx] py-[4rpx] bg-gray-100 text-gray-500 text-[20rpx] font-medium rounded-[8rpx]">
45 - :color="item.collected ? '#F59E0B' : '#9CA3AF'" class="mr-[8rpx]" /> 60 + PDF
46 - <span :class="['text-[24rpx]', item.collected ? 'text-[#F59E0B]' : 'text-[#9CA3AF]']"> 61 + </span>
47 - {{ item.collected ? '已收藏' : '收藏' }} 62 + <span class="text-[#9CA3AF] text-[22rpx]">
63 + {{ item.size }}
48 </span> 64 </span>
49 </div> 65 </div>
50 </div> 66 </div>
51 -
52 - <!-- Divider -->
53 - <div v-if="index < list.length - 1" class="h-[1px] bg-[#E5E7EB] w-full mb-[32rpx]"></div>
54 </div> 67 </div>
55 </div> 68 </div>
56 </div> 69 </div>
...@@ -335,3 +348,48 @@ const onView = (item) => { ...@@ -335,3 +348,48 @@ const onView = (item) => {
335 downloadAndOpenFile(item) 348 downloadAndOpenFile(item)
336 } 349 }
337 </script> 350 </script>
351 +
352 +<style lang="less" scoped>
353 +@keyframes slideIn {
354 + from {
355 + opacity: 0;
356 + transform: translateY(20rpx);
357 + }
358 +
359 + to {
360 + opacity: 1;
361 + transform: translateY(0);
362 + }
363 +}
364 +
365 +.material-item {
366 + animation: slideIn 0.5s cubic-bezier(0.2, 0.8, 0.2, 1) backwards;
367 +}
368 +
369 +/* 收藏成功的动画 */
370 +.is-collected {
371 + animation: heartBeat 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275);
372 +}
373 +
374 +@keyframes heartBeat {
375 + 0% {
376 + transform: scale(1);
377 + }
378 +
379 + 14% {
380 + transform: scale(1.3);
381 + }
382 +
383 + 28% {
384 + transform: scale(1);
385 + }
386 +
387 + 42% {
388 + transform: scale(1.3);
389 + }
390 +
391 + 70% {
392 + transform: scale(1);
393 + }
394 +}
395 +</style>
......