Prompt file imported from lxKylin/yucheng-mini (
.codex/prompts/M1.prompt.md). Copyright stays with the author.
M1 · 基础架构模块开发
任务概述
你是一名熟练的 Taro 4 + React 18 + TypeScript 专家。请按照以下规范,逐步完成 M1 基础架构模块的全部开发内容。完成每个子任务后自行验证,确认无误再进入下一个。
当前项目状态
- Taro 4.2.0 + React 18 + TypeScript + Vite 已初始化,
pnpm dev:weapp可无报错启动 @taroify/core ^0.9.2已安装- Zustand 尚未安装
- 当前仅有
src/pages/index/index.tsx占位页 src/styles/目录存在但为空src/assets/tabbar/目录存在但为空src/constants/、src/types/、src/utils/目录存在但无文件
UI 设计规范(来自 ui4.0/index.html)
色板严格遵守,禁止在代码中出现内联色值:
| 变量名 | 色值 |
|---|---|
$bg |
#f3fbfc |
$card |
#ffffff |
$ink |
#12333d |
$ink-strong |
#0b2229 |
$muted |
#667e87 |
$quiet |
#8aa0a7 |
$line |
#d8ebef |
$line-soft |
#eaf4f6 |
$primary |
#0c839a |
$primary-deep |
#0d6478 |
$primary-soft |
#dff6fb |
$success |
#18845d |
$success-soft |
#e4f8ef |
$warning |
#b26412 |
$warning-soft |
#fff4df |
$danger |
#c94040 |
$danger-soft |
#fff0f0 |
$violet |
#6268c9 |
$violet-soft |
#f0f1ff |
$radius |
8px |
$radius-lg |
16px |
$shadow-soft |
0 10px 26px rgba(16,74,91,0.1) |
$shadow |
0 24px 54px rgba(16,74,91,0.16) |
$duration |
210ms |
字号体系:大字 44px(剩余天数)、标题 23-24px、次标题 16px、正文 14px、辅助 12px
间距体系:8px / 12px / 16px / 18px
圆角:卡片 $radius(8px),标签/按钮 999px
子任务 1:安装 Zustand
pnpm add zustand
安装后确认 package.json dependencies 中出现 zustand。
子任务 2:创建 TabBar 图标(SVG 内联 Base64)
微信小程序 TabBar 图标需要本地文件(不支持网络图片)。使用 SVG 文件。
在 src/assets/tabbar/ 下创建以下 8 个文件(inactive / active 各 4 个,使用 stroke 风格 SVG,尺寸 81×81):
图标主题:
home.svg/home-active.svg— 房子图标(首页)list.svg/list-active.svg— 列表图标(提醒列表)bell.svg/bell-active.svg— 铃铛图标(提醒中心)user.svg/user-active.svg— 用户图标(我的)
颜色规范:
- inactive stroke 色:
#8aa0a7($quiet) - active stroke 色:
#0c839a($primary) stroke-width="4"stroke-linecap="round"stroke-linejoin="round"fill="none"
子任务 3:配置页面路由(src/app.config.ts)
完整替换 src/app.config.ts 内容:
export default defineAppConfig({
pages: [
'pages/home/index',
'pages/list/index',
'pages/messages/index',
'pages/profile/index'
],
window: {
backgroundTextStyle: 'light',
navigationBarBackgroundColor: '#f3fbfc',
navigationBarTitleText: '愈历',
navigationBarTextStyle: 'black'
// 各页面通过自定义 AppBar 实现标题,导航栏保留原生但高度最小
},
tabBar: {
custom: false,
color: '#8aa0a7',
selectedColor: '#0c839a',
backgroundColor: '#ffffff',
borderStyle: 'white',
list: [
{
pagePath: 'pages/home/index',
text: '首页',
iconPath: 'assets/tabbar/home.svg',
selectedIconPath: 'assets/tabbar/home-active.svg'
},
{
pagePath: 'pages/list/index',
text: '提醒列表',
iconPath: 'assets/tabbar/list.svg',
selectedIconPath: 'assets/tabbar/list-active.svg'
},
{
pagePath: 'pages/messages/index',
text: '提醒中心',
iconPath: 'assets/tabbar/bell.svg',
selectedIconPath: 'assets/tabbar/bell-active.svg'
},
{
pagePath: 'pages/profile/index',
text: '我的',
iconPath: 'assets/tabbar/user.svg',
selectedIconPath: 'assets/tabbar/user-active.svg'
}
]
}
});
子任务 4:创建 4 个 TabBar 占位页面
每个页面包含 index.tsx、index.config.ts、index.scss 三个文件。
4.1 页面配置(index.config.ts)
每个页面的 index.config.ts 设置各自标题:
// pages/home/index.config.ts
export default definePageConfig({ navigationBarTitleText: '首页' });
// pages/list/index.config.ts
export default definePageConfig({ navigationBarTitleText: '提醒列表' });
// pages/messages/index.config.ts
export default definePageConfig({ navigationBarTitleText: '提醒中心' });
// pages/profile/index.config.ts
export default definePageConfig({ navigationBarTitleText: '我的' });
4.2 占位页面组件(index.tsx)
统一结构,以首页为例:
// src/pages/home/index.tsx
import { View, Text } from '@tarojs/components'
import { useLoad } from '@tarojs/taro'
import './index.scss'
export default function Home() {
useLoad(() => {
console.log('home loaded')
})
return (
<View className='page-placeholder'>
<Text className='page-placeholder__text'>首页 — 开发中</Text>
</View>
)
}
其余三个页面按相同模式创建,class 名 page-placeholder,文字分别为"提醒列表 — 开发中"、"提醒中心 — 开发中"、"我的 — 开发中"。
4.3 占位样式(index.scss)
每个页面的 index.scss 使用相同内容,引入全局变量:
@use '@/assets/styles/variables' as *;
.page-placeholder {
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background: $bg;
&__text {
color: $muted;
font-size: 15px;
}
}
⚠️ Taro Vite 路径别名:
@别名已在config/index.ts中通过alias配置指向src/,SCSS 文件中使用@use '@/assets/styles/variables' as *时需确认 vite 配置中别名包含 SCSS resolve。若遇到解析失败,改为相对路径@use '../../styles/variables' as *。
子任务 5:建立全局主题变量(src/assets/styles/variables.scss)
创建 src/assets/styles/variables.scss:
// ─── 背景色 ───────────────────────────────
$bg: #f3fbfc;
$bg-warm: #fff8ec;
$card: #ffffff;
$phone: #f7fbfc;
// ─── 文字色 ───────────────────────────────
$ink: #12333d;
$ink-strong: #0b2229;
$muted: #667e87;
$quiet: #8aa0a7;
// ─── 线条色 ───────────────────────────────
$line: #d8ebef;
$line-soft: #eaf4f6;
// ─── 主题色 ───────────────────────────────
$primary: #0c839a;
$primary-deep: #0d6478;
$primary-soft: #dff6fb;
// ─── 语义色 ───────────────────────────────
$success: #18845d;
$success-soft: #e4f8ef;
$warning: #b26412;
$warning-soft: #fff4df;
$danger: #c94040;
$danger-soft: #fff0f0;
$violet: #6268c9;
$violet-soft: #f0f1ff;
// ─── 圆角 ─────────────────────────────────
$radius: 8px;
$radius-lg: 16px;
$radius-pill: 999px;
// ─── 阴影 ─────────────────────────────────
$shadow: 0 24px 54px rgba(16, 74, 91, 0.16);
$shadow-soft: 0 10px 26px rgba(16, 74, 91, 0.1);
// ─── 动效时长 ─────────────────────────────
$duration: 210ms;
// ─── 字号 ─────────────────────────────────
$text-xs: 12px;
$text-sm: 13px;
$text-base: 14px;
$text-md: 15px;
$text-lg: 17px;
$text-xl: 22px;
$text-2xl: 24px;
$text-hero: 44px;
// ─── 间距 ─────────────────────────────────
$spacing-1: 4px;
$spacing-2: 8px;
$spacing-3: 12px;
$spacing-4: 16px;
$spacing-5: 18px;
$spacing-6: 24px;
子任务 6:全局基础样式(src/app.scss)
完整替换 src/app.scss:
@use '@/assets/styles/variables' as *;
// ─── 微信小程序基础重置 ───────────────────
page {
min-height: 100vh;
background: $bg;
color: $ink;
font-size: $text-base;
line-height: 1.5;
box-sizing: border-box;
// 微信小程序字体继承
font-family: -apple-system, 'PingFang SC', 'Helvetica Neue', sans-serif;
}
*,
*::before,
*::after {
box-sizing: border-box;
}
// ─── 基础复用类 ───────────────────────────
// 卡片
.card {
padding: $spacing-3;
border-radius: $radius;
background: $card;
border: 1px solid rgba(216, 235, 239, 0.86);
box-shadow: 0 8px 20px rgba(16, 74, 91, 0.07);
}
// 状态标签
.tag {
display: inline-flex;
align-items: center;
min-height: 26px;
padding: 0 9px;
border-radius: $radius-pill;
font-size: $text-xs;
font-weight: 900;
white-space: nowrap;
&--danger {
color: $danger;
background: $danger-soft;
}
&--warning {
color: $warning;
background: $warning-soft;
}
&--good {
color: $success;
background: $success-soft;
}
&--paused {
color: $violet;
background: $violet-soft;
}
}
// 按钮基础
.button {
min-height: 44px;
display: inline-flex;
align-items: center;
justify-content: center;
gap: 7px;
padding: 0 $spacing-3;
border-radius: $radius;
font-weight: 900;
border: none;
cursor: pointer;
&--primary {
color: #fff;
background: $primary;
}
&--soft {
color: $primary-deep;
background: $primary-soft;
}
&--danger {
color: #fff;
background: $danger;
}
&--success {
color: #fff;
background: $success;
}
&--ghost {
color: $ink;
background: #f2f7f8;
}
}
// 进度条
.progress {
height: 8px;
overflow: hidden;
border-radius: $radius-pill;
background: #ecf3f5;
&__bar {
height: 100%;
border-radius: inherit;
background: $primary;
transition: width $duration ease-out;
}
&--danger .progress__bar {
background: $danger;
}
&--warning .progress__bar {
background: $warning;
}
&--good .progress__bar {
background: $success;
}
}
// 指标格
.metric {
min-height: 68px;
padding: 10px;
border-radius: $radius;
background: $card;
border: 1px solid $line-soft;
box-shadow: 0 8px 18px rgba(16, 74, 91, 0.06);
&__value {
display: block;
color: $ink-strong;
font-size: $text-xl;
line-height: 1.15;
}
&__label {
display: block;
margin-top: 4px;
color: $muted;
font-size: $text-xs;
font-weight: 750;
}
}
⚠️ Taro SCSS 注意:Taro 小程序端不支持 CSS 自定义属性(
var(--xxx)),必须使用 SCSS 变量编译后的静态值。不要在 SCSS 输出中保留var()语法。
子任务 7:公共目录结构和占位文件
7.1 类型定义占位(src/types/index.ts)
// M1 阶段仅建立文件,M2 将填充完整类型
export {};
7.2 常量占位(src/constants/index.ts)
// M1 阶段仅建立文件,M2 将填充完整常量
export {};
7.3 公共组件目录结构
创建以下空目录(每个目录放置一个 .gitkeep 文件占位,或直接创建组件骨架):
src/components/AppBar/
src/components/MedicineCard/
src/components/StatusTag/
src/components/ProgressBar/
src/components/BottomSheet/
在每个目录下创建 index.tsx 骨架组件(以 AppBar 为例):
// src/components/AppBar/index.tsx
import { View, Text } from '@tarojs/components'
import './index.scss'
interface AppBarProps {
title: string
caption?: string
right?: React.ReactNode
}
export default function AppBar({ title, caption, right }: AppBarProps) {
return (
<View className='appbar'>
<View className='appbar__main'>
<Text className='appbar__title'>{title}</Text>
{caption && <Text className='appbar__caption'>{caption}</Text>}
</View>
{right && <View className='appbar__right'>{right}</View>}
</View>
)
}
// src/components/AppBar/index.scss
@use '@/assets/styles/variables' as *;
.appbar {
min-height: 58px;
display: flex;
align-items: center;
justify-content: space-between;
gap: $spacing-3;
padding-bottom: $spacing-2;
&__main {
flex: 1;
}
&__title {
color: $ink-strong;
font-size: $text-2xl;
line-height: 1.16;
font-weight: 920;
}
&__caption {
display: block;
margin-top: 2px;
color: $muted;
font-size: $text-xs;
font-weight: 700;
}
&__right {
flex: 0 0 auto;
}
}
其余组件(MedicineCard、StatusTag、ProgressBar、BottomSheet)同样创建 index.tsx + index.scss 骨架,导出空组件(带注释"M3/M5/M6 开发时填充")。
子任务 8:验证 Vite 路径别名
检查 config/index.ts,确认 alias 配置中包含:
alias: {
'@': path.resolve(__dirname, '..', 'src'),
}
若不存在,添加该配置(需 import path from 'path')。
同时在 tsconfig.json 中确认 paths 包含:
{
"compilerOptions": {
"paths": {
"@/*": ["src/*"]
}
}
}
验收检查清单
完成所有子任务后,依次验证:
- Zustand 安装:
package.json中出现"zustand"依赖 - 路由配置:
app.config.ts包含 4 个 TabBar 页面路径 - SVG 图标:
src/assets/tabbar/下存在 8 个.svg文件 - 占位页面:4 个页面目录各有
index.tsx+index.config.ts+index.scss - SCSS 变量:
src/styles/variables.scss存在且包含全部色板变量 - 全局样式:
src/app.scss非空,包含.card、.tag、.button、.progress、.metric类 - 组件目录:
src/components/下 5 个子目录各有骨架文件 - 编译无报错:运行
pnpm dev:weapp,终端无 TypeScript / SCSS 编译错误 - TabBar 切换:在微信开发者工具中,4 个 Tab 可正常切换,各显示占位文字
- TabBar 颜色:选中色为
#0c839a,未选中为#8aa0a7 - Zustand import:在任意页面文件顶部加入
import { create } from 'zustand',编译通过后删除
重要约束
- 禁止内联色值:所有颜色必须通过 SCSS 变量引用,不得出现
color: #0c839a这类硬编码 - Taro 组件:使用
@tarojs/components中的View、Text、Image等,不使用 HTML 标签 - 微信小程序兼容:不使用
document、window、localStorage,微信端存储用Taro.setStorageSync - SCSS 模块化:每个组件的样式文件独立,通过
@use '@/assets/styles/variables' as *引入变量,不使用@import(已废弃) - 不提前实现业务逻辑:M1 阶段仅建立架构骨架,业务逻辑在 M2+ 阶段实现
