hookehuyr

fix(IconFont): 修复动态切换图标名称时图标不更新的问题

为 IconFont 组件添加 key 属性,强制其在图标名称变化时重新渲染,解决因 NutUI 组件未正确响应 props 变化导致的问题。

同时优化产品详情页的收藏图标交互与视觉:
- 将收藏按钮移至标题右侧,采用 Flexbox 布局避免长标题遮挡
- 统一使用 NutUI 标准图标名称(Heart/HeartFill)
- 为收藏按钮添加圆形背景与阴影,增强视觉反馈
- 优化热卖标签样式,采用玻璃拟态设计
......@@ -5,6 +5,20 @@ All notable changes to this project will be documented in this file.
## [Unreleased]
### Changed
- 优化 "产品详情" 页面 (`src/pages/product-detail`):
- 修复收藏图标状态切换无效的问题(修正图标名称为 NutUI 标准命名 `Heart`/`HeartFill`
- 优化顶部操作区视觉体验,统一 "热卖" 标签与 "收藏" 按钮风格,采用玻璃拟态(Glassmorphism)设计
- 增强收藏按钮交互反馈,增加白色圆形背景与阴影,确保在任意 Banner 背景下均清晰可见
- 调整产品标题与收藏按钮布局:
- 将收藏按钮移至标题右侧,采用 Flexbox 布局实现左右对齐
- 标题自适应占据剩余空间,收藏按钮固定在右侧,避免长标题遮挡按钮
### Fixed
- 修复 `IconFont` 组件在动态切换 `name` 属性时图标不更新的问题:
- 问题原因:NutUI 的 `IconFont` 组件在某些环境下未正确响应 props 变化
- 解决方案:在 `src/components/IconFont.vue` 中添加 `:key="name"`,强制组件在图标名称变化时重新渲染
### Changed
- 全量替换项目内 IconFont 调用为 `@nutui/icons-vue-taro``IconFont` 组件,统一使用 `class` 属性,移除自定义封装组件依赖
- 优化 "帮助中心" 页面 (`src/pages/help-center`):
- 重构 "联系客服" 弹窗,将硬编码数据提取为 `contactMethods` 数组,并优化样式布局
......
......@@ -6,7 +6,7 @@
* @Description: 图标字体组件
-->
<template>
<IconFontBase :name="name" :size="size" :color="color" :class="customClass" />
<IconFontBase :key="name" :name="name" :size="size" :color="color" :class="customClass" />
</template>
<script setup>
......
......@@ -13,29 +13,30 @@
:src="bannerImage"
mode="aspectFill"
/>
<div class="absolute top-[32rpx] right-[32rpx] flex gap-[16rpx]">
<div class="absolute top-[32rpx] right-[32rpx] flex items-center gap-[16rpx]">
<!-- Hot Tag -->
<div class="bg-red-500 text-white text-[24rpx] px-[16rpx] py-[8rpx] rounded-full shadow-sm">
<div class="bg-red-500 text-white text-[24rpx] px-[20rpx] py-[10rpx] rounded-full shadow-sm backdrop-blur-sm bg-opacity-90">
热卖
</div>
</div>
</div>
<!-- Product Header -->
<div class="relative mt-[-40rpx] bg-white rounded-t-[40rpx] px-[40rpx] pt-[48rpx] pb-[40rpx] z-10">
<div class="flex items-start justify-between mb-[24rpx]">
<h1 class="text-[#1F2937] text-[44rpx] font-bold flex-1 mr-[24rpx] leading-[1.2]">终身寿险尊享版</h1>
<!-- Favorite Button -->
<div
class="w-[64rpx] h-[48rpx] rounded-full shadow-md flex items-center justify-center"
:class="isCollected ? 'bg-[#F59E0B]' : 'bg-white'"
class="w-[72rpx] h-[72rpx] flex-shrink-0 flex items-center justify-center rounded-full bg-gray-50 active:scale-95 transition-transform"
@tap="toggleCollect"
>
<IconFont
:name="isCollected ? 'StarFill' : 'Star'"
:size="20"
:color="isCollected ? 'white' : '#9CA3AF'"
:name="isCollected ? 'heart-fill' : 'heart'"
size="24"
:color="isCollected ? '#EF4444' : '#9CA3AF'"
/>
</div>
</div>
</div>
<!-- Product Header -->
<div class="relative mt-[-40rpx] bg-white rounded-t-[40rpx] px-[40rpx] pt-[48rpx] pb-[40rpx] z-10">
<h1 class="text-[#1F2937] text-[44rpx] font-bold mb-[24rpx]">终身寿险尊享版</h1>
<div class="flex flex-wrap gap-[16rpx]">
<div class="px-[16rpx] py-[6rpx] bg-red-50 rounded-[8rpx]">
......@@ -71,7 +72,7 @@
<div class="flex flex-col gap-[32rpx]">
<div v-for="(feature, index) in features" :key="index" class="flex items-start">
<div class="w-[48rpx] h-[48rpx] rounded-full bg-blue-50 flex items-center justify-center mr-[24rpx] flex-shrink-0">
<IconFont name="check" size="14" color="#2563EB" />
<IconFont name="Check" size="14" color="#2563EB" />
</div>
<div class="flex-1">
<div class="text-[#1F2937] text-[28rpx] font-medium leading-[1.4]">{{ feature.title }}</div>
......