feat: 初始化后四日内容

This commit is contained in:
arthur
2026-09-28 17:55:58 +08:00
parent 9b7ab80fc1
commit 7b7181f2de
5 changed files with 517 additions and 7 deletions
+144
View File
@@ -0,0 +1,144 @@
# Day_4:把练习变成项目——做个人信息卡片
> 前三天的成果都保留:Day_1 的 Expo 应用、Day_2 的命令行练习、Day_3 的 Git 仓库。今天把应用代码纳入 Day_3 的仓库,接下来只在这一份项目上迭代。
预计用时:45~60 分钟。
## 今天要理解什么
- 一个项目不只是截图:源码、依赖清单、说明文档和提交历史要放在一起。
- React Native 用 `View` 布局、用 `Text` 显示文字、用 `StyleSheet` 管理样式。
- 组件是一块可以命名、复用的界面;props 是传给组件的数据。
## 1. 整理唯一的项目目录
Day_3 已经有 `app-rookie-你的名字` 仓库,里面有 `README.md` 和 `Day_3.txt`。Day_1 的 `CampusHelper` 是另一个目录。今天要把 **`CampusHelper` 目录里的项目文件**复制到 `app-rookie-你的名字` 的**根目录**,让后者成为以后唯一继续修改的应用项目。
复制前先确认两个目录的位置。可以用文件管理器或 VS Code 完成复制;保留 Day_3 仓库原有的 `README.md`、`Day_3.txt`,暂时不要用 Expo 模板的 README 覆盖它们。项目源码和配置(如 `package.json`、lock 文件、`app.json`、`.gitignore`、`app/` 或 `src/`、`assets/`)都要复制;**不要复制** `node_modules/`、`.expo/` 或 Day_1 项目里的 `.git/`。注意 `.gitignore` 是要保留的普通配置文件,`.git/` 才是不能复制的仓库历史目录。Day_1 的原目录暂时留着,不必删除。
整理后应该类似:
```text
app-rookie-你的名字/
├─ README.md ← Day_3 已有,Day_7 再完善
├─ Day_3.txt ← Day_3 已有
├─ package.json ← 从 CampusHelper 复制
├─ package-lock.json ← 从 CampusHelper 复制(如果有)
├─ app/ 或 src/app/ 或 App.tsx
└─ assets/ ...
```
在这个仓库根目录运行:
```bash
pwd
git status
npm install
npx expo start
```
手机上仍能打开 Day_1 的页面,才算迁移成功。以后所有 `npm`、`npx expo` 和 `git` 命令都在这个**包含 `package.json` 的仓库根目录**执行。若 `git status` 显示 `node_modules`、`.expo` 或嵌套的 `CampusHelper/.git`,先不要暂存,检查复制范围和 `.gitignore`;不确定时保留原文件并请学长学姐一起检查。
## 2. 找到首页,不预设模板目录
Day_1 没有固定模板版本,所以先找你实际修改过的入口页面。常见位置是 `App.tsx`、`app/index.tsx`、`app/(tabs)/index.tsx`、`src/app/index.tsx` 或 `src/app/(tabs)/index.tsx`。如果看到 `_layout.tsx`,先不要改它;它负责页面布局或导航。默认 Expo 模板可能已经带有标签页,今天只修改首页内容,不需要重建项目。
在与 `app/` 同级的位置创建 `components/`;如果入口是根目录的 `App.tsx`,就在根目录创建 `components/`。新建 `components/ProfileCard.tsx`:
```tsx
import { StyleSheet, Text, View } from 'react-native';
type ProfileCardProps = {
name: string;
major: string;
goal: string;
};
export default function ProfileCard({ name, major, goal }: ProfileCardProps) {
return (
<View style={styles.card}>
<Text style={styles.name}>{name}</Text>
<Text style={styles.detail}>专业:{major}</Text>
<Text style={styles.detail}>想学习:{goal}</Text>
</View>
);
}
const styles = StyleSheet.create({
card: { padding: 20, borderRadius: 16, backgroundColor: '#ffffff' },
name: { fontSize: 24, fontWeight: '700', color: '#1e3a8a' },
detail: { marginTop: 10, fontSize: 16, color: '#334155' },
});
```
在首页导入 `ProfileCard`,用自己的信息渲染它:
```tsx
<ProfileCard name="你的姓名" major="你的专业" goal="你想学习的技术" />
```
导入路径由首页位置决定:
| 首页文件 | 导入语句 |
| --- | --- |
| `App.tsx` | `import ProfileCard from './components/ProfileCard';` |
| `app/index.tsx` 或 `src/app/index.tsx` | `import ProfileCard from '../components/ProfileCard';` |
| `app/(tabs)/index.tsx` 或 `src/app/(tabs)/index.tsx` | `import ProfileCard from '../../components/ProfileCard';` |
注意:若项目使用 `src/app/`,组件目录应是 `src/components/`。首页的 `return` 需要一个最外层容器,例如 `ScrollView`;普通文字必须放进 `Text`。保留或替换模板原有的演示内容均可,但别误删其他路由或配置文件。
如果不知道把卡片放在哪里,可以先把首页原来的 `return` 内容换成下面的最小结构,并补上 `ScrollView`、`Text` 的导入:
```tsx
return (
<ScrollView contentContainerStyle={{ padding: 20 }}>
<Text>CampusHelper</Text>
<ProfileCard name="你的姓名" major="你的专业" goal="你的目标" />
</ScrollView>
);
```
## 今日任务
1. 让 Day_3 的仓库能够启动 Day_1 的 Expo 应用。
2. 首页显示独立的 `ProfileCard`,包含真实的姓名、专业和学习目标。
3. 自己改动至少两处样式,并再增加一条个人信息。
4. 在仓库 `README.md` 中增加一句项目目标:这个应用准备帮助谁、解决什么小问题。
这一天的重点是“把已有代码整理成可以继续维护的项目”,不需要做复杂的界面。
## 留下第一个应用里程碑
```bash
git status
git diff
```
确认暂存内容只包含应用源码、配置、lock 文件和今天更新的说明;不要提交缓存或 `node_modules`。可在 VS Code 源代码管理面板逐个暂存相关文件。`git diff` 不显示未跟踪的新文件,暂存后再用 `git diff --staged` 检查,随后运行:
```bash
git diff --staged
git status
git commit -m "feat: start campus helper"
git push
```
## 验收标准
- [ ] 仍是 Day_3 的同一个个人 Git 仓库,没有再新建远程仓库
- [ ] 仓库根目录有 `package.json`,`npx expo start` 能启动应用
- [ ] 首页有自己写的个人信息卡片,且能解释 `View`、`Text`、props 的作用
- [ ] 原有 Day_3 提交仍能在 `git log --oneline` 中看到
- [ ] 本次提交不含 `node_modules/`、`.expo/` 或嵌套 `.git/`
提交:应用截图、仓库链接、`git log --oneline -4` 截图。
## 遇到问题
**找不到 `App.tsx`:**默认 Expo 模板可能使用 `app/` 或 `src/app/`。找首页 `index.tsx`,不要新建第二套入口。
**`Unable to resolve ProfileCard`:**确认 `components/` 与 `app/` 的相对位置,按上表检查 `../` 的层数。
**`npm install` 找不到 `package.json`:**用 `pwd`、`ls` 确认你站在仓库根目录,并检查复制时是否遗漏了配置文件。
**页面空白或红屏:**先读终端第一条错误;可对照 Day_1 原项目的同一个文件逐步定位,不要删除整个项目重来。
+104
View File
@@ -0,0 +1,104 @@
# Day_5:让页面回应点击——学习打卡
> 今天只给昨天的项目增加一项能力:点击按钮,数字和提示文字会变化。
预计用时:40~60 分钟。
## 今天要理解什么
- `Pressable` 是可点击的区域,`onPress` 指定点击时运行的函数。
- `useState` 保存会变化的界面数据;调用更新函数后,React 会重新显示页面。
- 新功能要接在昨天的首页上,而不是另建一个 Expo 项目。
## 1. 从昨天的仓库继续
进入 Day_3 的 `app-rookie-你的名字` 仓库,也就是 Day_4 已经可以启动 Expo 的目录:
```bash
pwd
git status
git pull
npx expo start
```
先确认昨天的个人信息仍能显示。若 `git status` 有未提交修改,先弄清来源再继续,不要直接覆盖。
## 2. 写一个会变化的组件
在 Day_4 的 `components/` 旁边新建 `CheckInCard.tsx`:
```tsx
import { useState } from 'react';
import { Pressable, StyleSheet, Text, View } from 'react-native';
export default function CheckInCard() {
const [count, setCount] = useState(0);
return (
<View style={styles.card}>
<Text style={styles.title}>学习打卡</Text>
<Text>今天完成了 {count} 次学习</Text>
<Text>{count === 0 ? '从一次尝试开始吧' : '继续保持!'}</Text>
<Pressable
style={styles.button}
onPress={() => setCount((current) => current + 1)}
>
<Text style={styles.buttonText}>完成一次</Text>
</Pressable>
</View>
);
}
const styles = StyleSheet.create({
card: { marginTop: 16, padding: 20, borderRadius: 16, backgroundColor: '#ffffff' },
title: { marginBottom: 12, fontSize: 20, fontWeight: '700' },
button: { marginTop: 16, padding: 14, borderRadius: 10, backgroundColor: '#2563eb' },
buttonText: { color: '#ffffff', textAlign: 'center', fontWeight: '700' },
});
```
`count` 是当前值,`setCount` 负责更新。`current => current + 1` 表示“在上一次的值上加一”。把 `CheckInCard` 导入昨天的首页,放在 `ProfileCard` 下方;导入路径沿用 Day_4 的表,只把文件名改成 `CheckInCard`。
## 今日任务
1. 点击“完成一次”,数字加 1,提示文字从“从一次尝试开始吧”变成“继续保持!”。
2. 自己增加“重置”按钮,点击后数字回到 0。
3. 次数达到 3 时,再显示一句你写的鼓励语。
4. 原有个人信息卡片不能消失;在小屏手机上也能看见按钮。
提示:重置使用 `setCount(0)`;条件显示可以参考 `count >= 3 && <Text>……</Text>`。今天的数据只在应用运行期间保留,重新打开后归零是正常的,还没有学习本地存储。
## 项目记录
在项目 README 的“学习记录”中,用两句话写清楚:今天增加了什么功能,以及 `count` 与普通变量有什么区别。提交前执行:
```bash
git status
git diff
```
逐个暂存今天改动的首页、`CheckInCard.tsx` 和 README,然后:
```bash
git commit -m "feat: add study check-in"
git push
git log --oneline -4
```
## 验收标准
- [ ] 在 Day_4 的同一个应用中完成,个人信息卡片仍可见
- [ ] 点击增加、重置、达到 3 次的提示都正确
- [ ] 能指出组件里哪一行定义 state、哪一行处理点击
- [ ] README 有当天学习记录,Git 历史保留 Day_4 的提交
提交:0 次和 3 次时的截图,以及包含 Day_4、Day_5 的 Git 历史截图。
## 遇到问题
**一打开页面就自动加一:**`onPress` 要接收函数,不要写成立即执行的函数调用。
**提示文字不变化:**检查页面显示的是否是 `count`,以及按钮是否调用了 `setCount`。
**页面被挡住:**优先让首页外层滚动,不要给卡片写固定高度。
+118
View File
@@ -0,0 +1,118 @@
# Day_6:把重复内容变成数据——校园活动列表
> 昨天学会了让一个组件变化;今天学习如何用一份数据生成多个相似的界面。
预计用时:50~70 分钟。
## 今天要理解什么
- 数组保存多条活动,对象描述一条活动。
- `FlatList` 根据数据渲染列表,不需要复制粘贴多份卡片 JSX。
- 每条数据要有稳定且唯一的 `id`。
- 数据、组件和首页各有职责,项目会更容易修改。
## 1. 先确认旧功能
在 Day_4、Day_5 一直使用的仓库根目录运行:
```bash
git status
git pull
npx expo start
```
确认个人信息和打卡按钮仍可用。今天不新建项目,也不安装导航库。
## 2. 把活动写成数据
在与 `app/` 同级的位置新建 `data/activities.ts`;如果使用 `App.tsx`,就在仓库根目录建 `data/`。如果项目是 `src/app/`,则建 `src/data/`。
```ts
export type Activity = {
id: string;
title: string;
time: string;
location: string;
};
export const activities: Activity[] = [
{ id: 'club', title: '社团开放日', time: '周三 16:00', location: '活动中心' },
{ id: 'code', title: 'APP 开发分享会', time: '周五 19:00', location: '教学楼 201' },
{ id: 'run', title: '校园夜跑', time: '周六 19:30', location: '操场' },
];
```
`id` 不显示给用户,但用来区分活动。新增活动时只增加一条数据,不需要再复制一整块界面。
## 3. 在首页渲染列表
从 `react-native` 导入 `FlatList`、`Text`、`View` 和 `StyleSheet`,再从 `data/activities.ts` 导入数据。相对路径规则与 Day_4 的 `components/` 相同,只需将 `components` 改为 `data`。
参考核心写法:
```tsx
<FlatList
data={activities}
keyExtractor={(item) => item.id}
renderItem={({ item }) => (
<View style={styles.activityCard}>
<Text style={styles.activityTitle}>{item.title}</Text>
<Text>{item.time} · {item.location}</Text>
</View>
)}
ListHeaderComponent={
<View>
<Text style={styles.pageTitle}>CampusHelper</Text>
<ProfileCard name="你的姓名" major="你的专业" goal="你的目标" />
<CheckInCard />
<Text style={styles.sectionTitle}>校园活动</Text>
</View>
}
contentContainerStyle={styles.content}
/>
```
在 `StyleSheet.create` 中为 `activityCard`、`activityTitle`、`pageTitle`、`sectionTitle` 和 `content` 写样式。`content` 可以先写 `{ padding: 20, paddingBottom: 40 }`。把首页原来的外层 `ScrollView` 换成 `FlatList`,**不要把 `FlatList` 放进 `ScrollView`**;`ListHeaderComponent` 负责放置昨天已有的内容。
## 今日任务
1. 至少展示 4 条活动,其中 1 条由你自己设计。
2. 每条活动显示名称、时间、地点;`id` 不重复。
3. 只改 `activities.ts` 中的一条活动名称,观察界面是否跟着变化。
4. 个人信息和打卡功能仍然存在,列表能在小屏手机上滚动。
请用自己的话回答:如果下周要增加第五条活动,应改哪个文件?为什么不需要复制一块 JSX?
## 项目记录与提交
在 README 中增加“当前功能”列表,并写下今天的答案。提交前检查:
```bash
git status
git diff
```
逐个暂存首页、`data/activities.ts` 和 README,再提交:
```bash
git commit -m "feat: show campus activities"
git push
```
## 验收标准
- [ ] 仍在同一个 Git 仓库开发,旧功能可用
- [ ] 使用 `FlatList`,且 `keyExtractor` 返回唯一 `id`
- [ ] 至少 4 条活动,新增活动只需修改数据文件
- [ ] 没有把 `FlatList` 嵌套在同方向滚动的 `ScrollView` 中
- [ ] README 说明了当前功能,Git 历史有 Day_6 提交
提交:完整列表截图和 `git log --oneline -5` 截图。
## 遇到问题
**列表提示缺少 key:**检查每条活动是否有不同的 `id`,以及 `keyExtractor` 是否使用了它。
**活动只显示一部分:**确认外层不是固定高度的 `View`,并尝试向下滚动。
**组件导入失败:**检查 `components/`、`data/` 与 `app/` 是否按 Day_4 的规则放在同级。
+120
View File
@@ -0,0 +1,120 @@
# Day_7:完成第一个可讲清楚的项目
> 最后一天的目标不是堆功能,而是让 `CampusHelper` 能演示、能说明、能从 Git 历史看出成长过程。
预计用时:60~80 分钟。
## 先回顾项目
在 Day_3 的同一个仓库中运行:
```bash
git status
git pull
npx expo start
```
依次检查:个人信息是否正确、打卡能否增加和重置、活动列表是否能滚动、4 条活动是否都有不同内容。旧功能坏了,先修复再继续。
## 1. 给活动增加“想参加”状态
这是 Day_5 的 state 和 Day_6 的列表的一次组合。因为需要记住**哪些活动**被选中,状态应放在渲染整个列表的首页组件里,而不是只放在单条文字中。
在首页导入 `useState` 与 `Pressable`,在组件开头添加:
```tsx
const [joinedIds, setJoinedIds] = useState<string[]>([]);
function toggleJoin(id: string) {
setJoinedIds((current) =>
current.includes(id)
? current.filter((item) => item !== id)
: [...current, id]
);
}
```
`joinedIds` 是“想参加的活动 ID”列表。点击未选中的活动时加入 ID,再点一次时移除。给 Day_6 的 `FlatList` 增加 `extraData={joinedIds}`,让列表知道选中状态变了;在 `renderItem` 的活动卡片里增加:
```tsx
<Pressable onPress={() => toggleJoin(item.id)}>
<Text>{joinedIds.includes(item.id) ? '取消想参加' : '我想参加'}</Text>
</Pressable>
```
在 `ListHeaderComponent` 里显示汇总:
```tsx
<Text>想参加的活动:{joinedIds.length} 个</Text>
```
请给按钮加上足够的间距或背景色,让它看起来可以点击。这个版本**不保存到手机存储**,重新启动应用后状态归零是预期行为;不要把它描述成真实的报名系统。
## 2. 做一次产品检查
想象一位刚入学的同学第一次打开你的应用。选择至少 2 项改进:
- 把示例姓名、目标或活动改成与你所在学校有关的真实内容。
- 统一卡片颜色、间距和字号,让用户知道标题、说明、按钮各是什么。
- 打卡达到 3 次时显示更友好的鼓励语。
- 给“我想参加”按钮增加已选中时的颜色变化。
- 为活动补充一句简介,帮助用户判断是否感兴趣。
- 修复你自己在测试中发现的一个小问题。
每项改进都要能在手机上看到或操作。记录一个“下个版本再做”的想法,例如真正的报名、数据持久化或活动详情;把想法写进 README,不要求今天实现。
## 3. 把 README 写成项目说明书
保留 Day_3 已有 README 中有价值的内容,再补齐以下信息:
- 项目一句话介绍:面向谁,解决什么小问题。
- 当前功能:个人信息、学习打卡、校园活动、想参加标记。
- 运行方法:进入含 `package.json` 的仓库根目录,执行 `npm install`、`npx expo start`。
- 项目结构:哪个文件是首页,`components/` 和 `data/` 各负责什么。
- 已知限制与下一步:例如打卡和想参加状态在重启后归零。
- 学习总结:这四天你遇到的一个问题和解决过程。
README 的目标是让另一个新生拿到仓库后知道“怎么运行、做了什么、还没做什么”。
## 4. 用自己的操作验收
- [ ] `npm install` 后能启动,没有红色报错
- [ ] 个人信息是自己的内容
- [ ] 打卡增加、重置、条件提示正常
- [ ] 至少 4 条活动可以滚动浏览
- [ ] 每条活动的“我想参加”都能独立切换,再点可取消
- [ ] 顶部想参加数量与实际选中的活动数一致
- [ ] README 如实说明功能和限制
- [ ] `git status` 中没有 `node_modules/`、`.expo/` 等缓存
发现问题时,先写下“操作 → 预期 → 实际”,再阅读终端第一条报错。修复后重新执行相关测试。
## 5. 留下清楚的版本记录
```bash
git status
git diff
git log --oneline --graph -8
```
你应该能看到 Day_3 的 Git 练习提交,以及 Day_4 到 Day_6 对**同一个仓库**的增量提交。通过 VS Code 源代码管理面板逐个暂存今天修改的源码和 README,再用 `git diff --staged` 核对暂存内容,然后执行:
```bash
git diff --staged
git commit -m "feat: finish campus helper v1"
git push
git status
```
若提示 `nothing to commit`,先看 `git status`:可能忘了暂存,也可能没有产生新改动。不要为了凑提交而改无关文件;不要使用 `git push --force`。
## 最终提交
1. 仓库链接和首页截图。
2. 一张选中两条活动、顶部数量为 2 的截图。
3. `git log --oneline --graph -8` 截图,能看到连续的项目迭代。
4. 100~200 字总结:你最明白的一个 React Native 概念,以及下个版本想解决的问题。
## 选做:认识页面导航
如果以上内容全部完成,还有余力,可以探索默认 Expo 模板自带的页面切换:找一找 `app/` 或 `src/app/` 中的页面文件,观察它们如何对应应用中的页面。默认模板通常已经包含 [Expo Router](https://docs.expo.dev/router/introduction/);不需要为了本题再安装一套导航库。这个选做内容不影响基本验收。
+31 -7
View File
@@ -2,7 +2,30 @@
APP 部 2026 纳新每日一题(开发基础 / 命令行 / Git / React Native)。
每个 `Day_1` ~ `Day_7` 文件夹中都有当天教学与任务。建议每天投入 30~60 分钟:先读 `README.md`,再完成任务,并将代码、运行截图或仓库链接提交到当天工单。
每个 `Day_1` ~ `Day_7` 文件夹中都有当天教学与任务。建议每天投入约 30~80 分钟(以当天题目为准):先读 `README.md`,再完成任务,并将代码、运行截图或仓库链接提交到当天工单。
## 项目开发启蒙
前三天按各自题目完成:Day_1 创建 `CampusHelper` Expo 应用,Day_2 练习命令行,Day_3 建立个人 Git 仓库。Day_4 将 Day_1 的应用文件整理进 Day_3 的仓库;Day_5~Day_7 只在这个仓库里继续开发,不再创建新的应用或远程仓库。
每天固定执行同一套版本管理循环:
```text
进入含 package.json 的个人仓库 → git status / git pull → 编码并运行 → git diff
→ git add 指定文件 → git commit → git push
```
推荐的提交里程碑:
| 日期 | 项目增量 | 推荐 commit |
| --- | --- | --- |
| Day_3 | 建立个人 Git 练习仓库 | `docs: 完成 Day_3 的 git 练习` |
| Day_4 | 将应用纳入仓库,完成个人信息卡片 | `feat: 开始开发校园助手` |
| Day_5 | 学习打卡计数器 | `feat: 加入学习打卡器` |
| Day_6 | 数据驱动的校园活动列表 | `feat: 展示校园活动` |
| Day_7 | 想参加标记、测试与项目说明 | `feat: 完成校园助手_v1` |
> 开始当天任务前若 `git status` 不是干净状态,先处理昨天未提交的修改;不要带着来历不明的改动继续写。
## 课程安排
@@ -13,10 +36,10 @@ APP 部 2026 纳新每日一题(开发基础 / 命令行 / Git / React Native
| `Day_3` | Git 入门:clone / add / commit / pull / push |
| `Day_4` | React Native 页面基础:组件、JSX 与 StyleSheet |
| `Day_5` | React Native 交互:事件、state 与 `useState` |
| `Day_6` | 列表与导航:`FlatList`、参数与详情页 |
| `Day_7` | 综合完成一个 React Native 校园助手应用 |
| `Day_6` | 数据与列表:数组、对象、`FlatList` |
| `Day_7` | 综合实践:状态组合、测试、README 与版本回顾 |
> **目的:**帮助零基础同学建立开发习惯,理解项目、组件、状态、事件、列表与导航,并能阅读和修改一个简单的 React Native 应用。
> **目的:**帮助零基础同学建立项目意识与开发习惯,初步理解 React Native 的组件、样式、事件、状态和列表,并能说明自己如何逐步完成一个应用。
## 技术栈
@@ -25,12 +48,13 @@ APP 部 2026 纳新每日一题(开发基础 / 命令行 / Git / React Native
- React:用组件描述界面,用 state 管理会变化的数据。
- React Native:将 React 组件渲染为 Android / iOS 原生界面。
- Expo:提供适合入门的项目脚手架、开发服务器与真机预览流程。
- React Navigation:处理多页面应用的页面跳转。
默认 Expo 模板可能带有 Expo Router 页面结构;本阶段先使用已有首页,不要求额外安装导航库或掌握多页面路由。
不需要 Android Studio、Xcode 或微信开发者工具;使用 Expo Go 扫码即可在手机上预览。
## 最终项目:CampusHelper
第七天将完成一个小型校园助手应用,至少包含个人信息卡片、学习打卡计数器、校园活动列表,以及活动详情页与报名状态切换。
第七天将完成一个小型校园助手应用,至少包含个人信息卡片、学习打卡计数器、校园活动列表和“想参加”标记。该标记只是本地界面状态,不代表真实报名,也不会在重启后保留。
完成后,你应能从项目目录启动开发服务器、修改一个组件、处理点击事件、更新 state、渲染列表、在页面间传递参数,并用 Git 保存修改。
完成后,你应能从仓库根目录启动开发服务器、修改组件、处理点击事件、更新 state、渲染列表,并用 Git 和 README 说明项目的功能、限制与迭代过程。