Prechádzať zdrojové kódy

📝 docs(stories): 更新首页UI重构计划中的组件集成方案

- 将TDesign原生小程序组件库依赖安装和配置方案,修改为创建Taro React版本的TDesign组件方案
- 新增5个自定义Taro React组件的创建任务:Search、Swiper、Icon、Toast和Tabs
- 更新组件使用方式,从使用原生小程序组件改为导入自定义Taro React组件
- 调整组件属性配置,如将indicator-dots改为indicatorDots以符合React命名规范
- 更新组件依赖说明,明确使用自定义Taro React组件而非原生小程序组件
- 添加组件转写说明,包括创建策略和实现示例
- 更新项目结构信息,明确自定义组件的存放路径
yourname 1 mesiac pred
rodič
commit
601cd2004c
1 zmenil súbory, kde vykonal 140 pridanie a 107 odobranie
  1. 140 107
      docs/stories/001.004.homepage-ui-refactor.md

+ 140 - 107
docs/stories/001.004.homepage-ui-refactor.md

@@ -39,30 +39,30 @@ Draft
   - [ ] 应用商品卡片间距和布局
   - [ ] 应用主色调(#fa550f, #fa4126)
 - [ ] 集成TDesign MiniProgram组件 (AC: 1, 5)
-  - [ ] 安装TDesign原生小程序组件库依赖
-    - [ ] 安装 `tdesign-miniprogram`
-    - [ ] 在 `mini/package.json` 中添加依赖
-  - [ ] 配置Taro项目支持原生小程序组件
-    - [ ] 在 `mini/config/index.js` 中配置小程序组件路径
-    - [ ] 在 `mini/app.config.ts` 中配置usingComponents
+  - [ ] 创建Taro React版本的TDesign组件
+    - [ ] 创建 `mini/src/components/tdesign-search/index.tsx` - Search组件
+    - [ ] 创建 `mini/src/components/tdesign-swiper/index.tsx` - Swiper组件
+    - [ ] 创建 `mini/src/components/tdesign-icon/index.tsx` - Icon组件
+    - [ ] 创建 `mini/src/components/tdesign-toast/index.tsx` - Toast组件
+    - [ ] 创建 `mini/src/components/tdesign-tabs/index.tsx` - Tabs组件
   - [ ] 使用TDesign search组件实现搜索栏
-    - [ ] 在首页组件中使用 `t-search` 组件
+    - [ ] 在首页组件中导入自定义Search组件
     - [ ] 配置搜索栏属性:placeholder、disabled、shape等
     - [ ] 应用tcb-shop-demo的搜索栏样式(圆角32rpx,高度64rpx)
   - [ ] 使用TDesign swiper组件实现轮播图
-    - [ ] 在首页组件中使用 `t-swiper` 组件
-    - [ ] 配置轮播图属性:autoplay、interval、indicator-dots等
+    - [ ] 在首页组件中导入自定义Swiper组件
+    - [ ] 配置轮播图属性:autoplay、interval、indicatorDots等
     - [ ] 实现轮播图数据绑定和图片展示
   - [ ] 使用TDesign icon组件实现图标
-    - [ ] 在首页组件中使用 `t-icon` 组件
+    - [ ] 在首页组件中导入自定义Icon组件
     - [ ] 使用搜索图标、购物车图标等
     - [ ] 配置图标颜色和大小匹配tcb-shop-demo设计
   - [ ] 使用TDesign toast组件实现提示
-    - [ ] 在首页组件中使用 `t-toast` 组件
+    - [ ] 在首页组件中导入自定义Toast组件
     - [ ] 实现加载状态、成功提示、错误提示等
     - [ ] 配置Toast样式和位置
   - [ ] 使用TDesign tabs组件实现分类切换
-    - [ ] 在首页组件中使用 `t-tabs` 和 `t-tab-panel` 组件
+    - [ ] 在首页组件中导入自定义Tabs组件
     - [ ] 配置分类数据源和切换逻辑
     - [ ] 实现分类切换时的商品列表更新
 - [ ] 测试和验证 (AC: 5)
@@ -77,8 +77,8 @@ Draft
 - **前端框架**: React 18.0.0
 - **小程序框架**: Taro 4.1.4
 - **样式系统**: Tailwind CSS + 自定义CSS (tcb-theme.css)
-- **组件库**: TDesign原生小程序组件 (tdesign-miniprogram)
-- **集成方式**: Taro中使用原生小程序组件
+- **组件库**: 自定义Taro React组件 (基于TDesign设计规范)
+- **集成方式**: 直接使用Taro React组件,无需原生组件集成
 
 ### 项目结构信息 [Source: architecture/source-tree.md]
 - **首页位置**: `mini/src/pages/index/index.tsx`
@@ -107,118 +107,151 @@ Draft
 - **主色调**: 搜索图标颜色、购物车按钮颜色、选中状态颜色使用 #fa550f 和 #fa4126
 
 ### 组件依赖
-- **TDesign原生小程序组件**: t-search, t-swiper, t-icon, t-toast, t-tabs
+- **自定义Taro React组件**: TDesignSearch, TDesignSwiper, TDesignIcon, TDesignToast, TDesignTabs
 - **自定义组件**: goods-list, goods-card, load-more
 
-### TDesign原生小程序组件集成说明
+### TDesign组件转写说明
 
-#### 1. 安装依赖
-```bash
-cd mini
-npm install tdesign-miniprogram
-```
-
-#### 2. 配置Taro项目
-
-**在 `mini/config/index.js` 中配置组件路径:**
-```javascript
-const config = {
-  // ... 其他配置
-  copy: {
-    patterns: [
-      {
-        from: 'node_modules/tdesign-miniprogram/miniprogram_dist/',
-        to: 'tdesign/',
-      },
-    ],
-  },
-}
-```
+#### 1. 组件创建策略
+- 基于TDesign原生组件源码转写成Taro React组件
+- 保持TDesign的设计规范和交互体验
+- 使用React Hooks和Taro API实现功能
+- 应用tcb-shop-demo的主题样式
 
-**在 `mini/app.config.ts` 中注册全局组件:**
-```typescript
-export default defineAppConfig({
-  usingComponents: {
-    't-search': 'tdesign/search/index',
-    't-swiper': 'tdesign/swiper/index',
-    't-icon': 'tdesign/icon/index',
-    't-toast': 'tdesign/toast/index',
-    't-tabs': 'tdesign/tabs/index',
-    't-tab-panel': 'tdesign/tabs/tab-panel/index',
-  },
-})
-```
-
-#### 3. 组件使用示例
+#### 2. 组件实现示例
 
-**Search组件**
+**Search组件 (mini/src/components/tdesign-search/index.tsx)**
 ```tsx
-<t-search
-  placeholder="搜索商品"
-  disabled={false}
-  shape="round"
-  class="rounded-[32rpx] h-[64rpx]"
-/>
-```
+import { useState } from 'react'
+import { View, Input } from '@tarojs/components'
+import TDesignIcon from '../tdesign-icon'
+
+interface SearchProps {
+  placeholder?: string
+  disabled?: boolean
+  shape?: 'round' | 'square'
+  value?: string
+  onChange?: (value: string) => void
+  onFocus?: () => void
+  onBlur?: () => void
+  onSubmit?: (value: string) => void
+}
 
-**Swiper组件**
-```tsx
-<t-swiper
-  autoplay
-  interval={3000}
-  indicator-dots
->
-  {banners.map((banner, index) => (
-    <swiper-item key={index}>
-      <image src={banner.image} mode="aspectFill" />
-    </swiper-item>
-  ))}
-</t-swiper>
+export default function TDesignSearch({
+  placeholder = '搜索商品',
+  disabled = false,
+  shape = 'round',
+  value = '',
+  onChange,
+  onFocus,
+  onBlur,
+  onSubmit
+}: SearchProps) {
+  const [focused, setFocused] = useState(false)
+
+  const handleInput = (e) => {
+    onChange?.(e.detail.value)
+  }
+
+  const handleFocus = () => {
+    setFocused(true)
+    onFocus?.()
+  }
+
+  const handleBlur = () => {
+    setFocused(false)
+    onBlur?.()
+  }
+
+  const handleConfirm = (e) => {
+    onSubmit?.(e.detail.value)
+  }
+
+  return (
+    <View className={`tdesign-search tdesign-search--${shape}`}>
+      <View className={`tdesign-search__input-box ${focused ? 'tdesign-search__input-box--focused' : ''}`}>
+        <TDesignIcon name="search" size="32rpx" color="#fa550f" />
+        <Input
+          type="text"
+          placeholder={placeholder}
+          disabled={disabled}
+          value={value}
+          onInput={handleInput}
+          onFocus={handleFocus}
+          onBlur={handleBlur}
+          onConfirm={handleConfirm}
+          className="tdesign-search__input"
+        />
+      </View>
+    </View>
+  )
+}
 ```
 
-**Icon组件**
+**Icon组件 (mini/src/components/tdesign-icon/index.tsx)**
 ```tsx
-<t-icon name="search" size="32rpx" color="#fa550f" />
-<t-icon name="cart" size="32rpx" color="#fa550f" />
-```
+import { View } from '@tarojs/components'
 
-**Toast组件**
-```tsx
-// 在TSX中需要通过ref调用
-import { createSelectorQuery } from '@tarojs/taro'
-
-const showToast = () => {
-  const query = createSelectorQuery()
-  query.select('#toast').node((res) => {
-    const toast = res.node
-    toast.show({
-      message: '操作成功',
-      theme: 'success',
-      duration: 2000,
-    })
-  }).exec()
+interface IconProps {
+  name: string
+  size?: string
+  color?: string
 }
 
-// 在render中
-<t-toast id="toast" />
+export default function TDesignIcon({ name, size = '32rpx', color = '#fa550f' }: IconProps) {
+  return (
+    <View
+      className={`tdesign-icon tdesign-icon--${name}`}
+      style={{ fontSize: size, color }}
+    >
+      {/* 使用Unicode或SVG图标 */}
+    </View>
+  )
+}
 ```
 
-**Tabs组件**
+**Swiper组件 (mini/src/components/tdesign-swiper/index.tsx)**
 ```tsx
-<t-tabs value={activeTab} bindchange={handleTabChange}>
-  {categories.map(category => (
-    <t-tab-panel key={category.id} label={category.name} value={category.id}>
-      <GoodsList categoryId={category.id} />
-    </t-tab-panel>
-  ))}
-</t-tabs>
+import { useState } from 'react'
+import { Swiper, SwiperItem, Image } from '@tarojs/components'
+
+interface SwiperProps {
+  images: string[]
+  autoplay?: boolean
+  interval?: number
+  indicatorDots?: boolean
+}
+
+export default function TDesignSwiper({
+  images = [],
+  autoplay = true,
+  interval = 3000,
+  indicatorDots = true
+}: SwiperProps) {
+  return (
+    <Swiper
+      className="tdesign-swiper"
+      autoplay={autoplay}
+      interval={interval}
+      indicatorDots={indicatorDots}
+      indicatorColor="#999"
+      indicatorActiveColor="#fa550f"
+    >
+      {images.map((image, index) => (
+        <SwiperItem key={index}>
+          <Image src={image} mode="aspectFill" className="tdesign-swiper__image" />
+        </SwiperItem>
+      ))}
+    </Swiper>
+  )
+}
 ```
 
-#### 4. 样式集成
-- 使用Tailwind CSS类名覆盖TDesign组件默认样式
+#### 3. 样式集成
+- 使用Tailwind CSS类名和自定义CSS
 - 应用tcb-theme.css中的主题变量
-- 确保组件样式与tcb-shop-demo设计保持一致
-- 注意:原生小程序组件使用 `class` 属性而不是 `className`
+- 保持与tcb-shop-demo设计的一致性
+- 使用标准的React className属性
 
 ### Testing