前端开发者的一天 — 工作纪实

A Documentary Walkthrough of a Frontend Developer's Workday

Vue 3 CSS/SCSS Vite DevTools 响应式设计 Code Review

📅 今天的主角:小李

属性
姓名小李
经验2年 Vue / React 前端开发
团队电商业务线 — 订单组
日期2026-03-18(周三)
今日任务商品评价展示页 — 从设计稿到上线
工具栈VS Code + Vue 3 + Vite + Chrome DevTools

09:00 早站会 — Daily Standup

场景 每天早上9点,团队在飞书群里开站会。每个人说三件事:昨天做了什么、今天要做什么、有没有卡住的地方。小李打开飞书,准备汇报。
💬 飞书群 — 电商订单组(8人)
—— 09:02 ——
老陈(技术负责人)
站会开始,大家依次说一下。小张先来?
小张(后端开发)
昨天:评价接口的 CRUD 写完了。今天:做分页和排序。没有 block。
小李(前端开发)👈
昨天:商品详情页改版完成,已经合并了。今天:做商品评价展示页,拿到设计稿就开始。没有 block。
王姐(QA)
昨天:回归测试商品详情页,发现2个小问题。今天:继续测。等评价页提测我会跟上。
小美(设计师)
评价页的设计稿已经放到 Figma 了,小李你看看,有问题找我。
小李(前端开发)
好的,马上去看 👍
老陈(技术负责人)
好,站会结束。大家开工。

📋 站会要点

昨天今天Block
小张(后端)评价接口 CRUD分页排序
小李(前端)商品详情页改版商品评价展示页
王姐(QA)回归测试继续测

09:20 拿到设计稿 — Figma Review

场景 设计师出的设计稿,前端要对照这个来做页面。注意看间距、字体大小、颜色值。小李打开 Figma,仔细研究"商品评价"页面的设计。
Figma 商品评价页设计稿 v2.3 — 我的电商项目 Last edited 10 min ago
📱 iPhone 14 Pro — 393 × 852
9:41 📶 🔋
商品评价
商品图
无线蓝牙耳机 Pro Max
已有 128 条评价
★★★★★ 4.8
4.8
★★★★★
128 条评价
5星
78%
4星
15%
3星
5%
2星
2%
1星
0%
✍️ 写评价
全部评价 (128)
小明同学 2026-03-15
★★★★★
音质很棒,降噪效果超好,续航也很给力。通勤必备!
花花世界 2026-03-14
★★★★☆
佩戴舒适度不错,就是价格略贵。
大海无量 2026-03-12
★★★★★
性价比超高...
设计稿看完了,这个页面大致分三块:评分汇总区、写评价表单、评价列表。我需要把这些拆成组件来做。

📐 设计稿标注提取

元素尺寸/间距颜色字体
页面标题16px bold#CDD6F4PingFang SC
商品图72×72, 圆角8px
评分数字24px bold#FF8C00
评价卡片padding 10px, 圆角8pxbg #f9f9f9
评价内容12px, 行高1.5#BAC2DE
按钮padding 10px, 圆角8pxbg #FF6B0013px bold white
评分条高度6px, 圆角3px#FF8C00 / #e0e0e0

09:40 建组件 + 搭页面 — Project Setup

场景 小李打开 VS Code,创建组件文件。根据设计稿拆分了4个组件:ReviewPage(页面)、ReviewForm(表单)、ReviewList(列表)、StarRating(星级评分)。
💡 组件拆分思路:就像搭积木一样,把页面拆成独立的小块。每个组件负责一块 UI,这样好维护、好复用。StarRating 以后在购物车、搜索页也能用到。
my-shop-frontend — Visual Studio Code
📄 ReviewPage.vue
📄 StarRating.vue
资源管理器
📂 src
📂 api
📂 assets
📂 components
📄 ReviewForm.vue
📄 ReviewList.vue
📄 StarRating.vue
📂 views
📂 product
📄 ReviewPage.vue ←
📂 router
📄 App.vue
📄 main.js
📄 package.json
📄 vite.config.ts
1<template>
2 <div class="review-page">
3 <h2>商品评价</h2>
4 <!-- 评价表单 -->
5 <ReviewForm
6 :productId="productId"
7 @submit="handleSubmit"
8 />
9 <!-- 评价列表 -->
10 <ReviewList :productId="productId" />
11 </div>
12</template>
13
14<script setup>
15import { ref } from 'vue'
16import { useRoute } from 'vue-router'
17import ReviewForm from '@/components/ReviewForm.vue'
18import ReviewList from '@/components/ReviewList.vue'
19
20const route = useRoute()
21const productId = ref(route.params.id)
22
23const handleSubmit = (formData) => {
24 console.log('提交评价', formData)
25}
26</script>
📊 组件层级图 — Component Tree
📄 ReviewPage
props ↓    events ↑
props ↓
📝 ReviewForm
events ↑ onSubmit
v-model
⭐ StarRating
props ↓ :productId
📋 ReviewList
expose ↑ refresh()
⬇️ props 向下传递数据   |   ⬆️ events 向上通知事件
页面结构搭好了,接下来写 StarRating 组件

10:00 写组件代码 — Component Development

场景 先写 StarRating 星级评分组件,这个组件最独立、最好测。然后写 ReviewForm 和 ReviewList。

⭐ StarRating.vue — 星级评分组件

StarRating.vue — my-shop-frontend
📄 ReviewPage.vue
⭐ StarRating.vue
1<template>
2 <div class="star-rating">
3 <span
4 v-for="star in 5"
5 :key="star"
6 :class="['star', { active: star <= modelValue }]"
7 @click="$emit('update:modelValue', star)"
8 >
9
10 </span>
11 </div>
12</template>
13
14<script setup>
15defineProps({
16 modelValue: {
17 type: Number,
18 default: 0
19 }
20})
21
22defineEmits(['update:modelValue'])
23</script>
24
25<style scoped>
26.star-rating {
27 display: inline-flex;
28 gap: 4px;
29}
30.star {
31 font-size: 20px;
32 color: #ddd;
33 cursor: pointer;
34 transition: color .2s;
35}
36.star.active {
37 color: #FFD700;
38}
39</style>

📝 ReviewForm.vue — 评价表单组件

ReviewForm.vue — my-shop-frontend
📝 ReviewForm.vue
1<template>
2 <div class="review-form">
3 <h3>写评价</h3>
4 <!-- 星级评分 -->
5 <div class="form-item">
6 <label>评分</label>
7 <StarRating v-model="form.rating" />
8 </div>
9 <!-- 评价内容 -->
10 <div class="form-item">
11 <label>评价内容</label>
12 <textarea
13 v-model="form.content"
14 placeholder="说说你的使用体验..."
15 rows="4"
16 />
17 </div>
18 <!-- 提交按钮 -->
19 <button class="submit-btn" @click="onSubmit">
20 提交评价
21 </button>
22 </div>
23</template>
24
25<script setup>
26import { reactive } from 'vue'
27import StarRating from './StarRating.vue'
28import { submitReview } from '@/api/review'
29
30const props = defineProps({
31 productId: { type: [String, Number], required: true }
32})
33const emit = defineEmits(['submit'])
34
35const form = reactive({
36 rating: 0,
37 content: ''
38})
39
40const onSubmit = async () => {
41 if (form.rating === 0) {
42 return alert('请先选择评分')
43 }
44 const res = await submitReview({
45 productId: props.productId,
46 rating: form.rating,
47 content: form.content
48 })
49 emit('submit', res.data)
50}
51</script>

📋 ReviewList.vue — 评价列表组件

ReviewList.vue — my-shop-frontend
📋 ReviewList.vue
1<template>
2 <div class="review-list">
3 <h3>全部评价 ({{ total }})</h3>
4 <!-- 加载状态 -->
5 <div v-if="loading" class="loading">加载中...</div>
6 <!-- 空状态 -->
7 <div v-else-if="list.length === 0" class="empty">
8 暂无评价,快来抢沙发~
9 </div>
10 <!-- 评价卡片 -->
11 <div v-else>
12 <ReviewCard
13 v-for="item in list"
14 :key="item.id"
15 :review="item"
16 />
17 </div>
18 </div>
19</template>
20
21<script setup>
22import { ref, onMounted } from 'vue'
23import { getProductReviews } from '@/api/review'
24
25const props = defineProps({
26 productId: { type: [String, Number], required: true }
27})
28
29const list = ref([])
30const loading = ref(false)
31const total = ref(0)
32
33const fetchList = async () => {
34 loading.value = true
35 const { data } = await getProductReviews(props.productId)
36 list.value = data.list
37 total.value = data.total
38 loading.value = false
39}
40
41onMounted(fetchList)
42
43// 暴露 refresh 方法给父组件调用
44defineExpose({ refresh: fetchList })
45</script>
组件代码写完了,接下来写样式(CSS)

10:30 写样式 — CSS / SCSS Styling

场景 对照设计稿的标注,小李用 SCSS 写页面样式。注意间距、圆角、颜色值都要和设计稿一致。
ReviewPage.vue <style> — my-shop-frontend
📝 Template
📜 Script
🎨 Style
1<style lang="scss" scoped>
2.review-page {
3 padding: 16px;
4 background: #f5f5f5;
5 min-height: 100vh;
6
7 /* 页面标题 */
8 h2 {
9 font-size: 16px;
10 font-weight: 600;
11 margin-bottom: 16px;
12 }
13
14 /* 评价卡片 */
15 .review-card {
16 background: white;
17 border-radius: 12px;
18 padding: 16px;
19 margin-bottom: 12px;
20 box-shadow: 0 1px 4px rgba(0,0,0,.06);
21 }
22}
23
24.review-form {
25 background: white;
26 border-radius: 12px;
27 padding: 16px;
28 margin-bottom: 16px;
29
30 .form-item {
31 margin-bottom: 12px;
32 }
33
34 label {
35 display: block;
36 font-size: 13px;
37 color: #666;
38 margin-bottom: 6px;
39 }
40
41 textarea {
42 width: 100%;
43 border: 1px solid #e0e0e0;
44 border-radius: 8px;
45 padding: 10px;
46 font-size: 13px;
47 resize: vertical;
48 }
49
50 .submit-btn {
51 background: #FF6B00;
52 color: white;
53 border: none;
54 border-radius: 8px;
55 padding: 10px;
56 width: 100%;
57 font-size: 14px;
58 font-weight: 600;
59 cursor: pointer;
60 }
61}
62
63.review-card {
64 .avatar { width: 36px; height: 36px; border-radius: 50%; }
65 .nickname { font-size: 14px; font-weight: 600; }
66 .content {
67 font-size: 13px; color: #666;
68 line-height: 1.6; margin-top: 8px;
69 }
70 .date { font-size: 11px; color: #999; margin-top: 6px; }
71}
72</style>

🌐 浏览器效果(本地开发环境)

🔒 http://localhost:5173/product/5001/reviews
商品评价
商品图
无线蓝牙耳机 Pro Max
已有 128 条评价
★★★★★ 4.8
写评价
评分
★★★★★
评价内容
说说你的使用体验...
提交评价
全部评价 (0)
加载中...
页面框架搭好了,样式也写好了。但是数据还没接上,评价列表是空的。接下来去调后端接口拿数据。

11:00 调后端接口 — API Integration

场景 小李先写 API 请求函数,然后在浏览器里调用。结果遇到了 CORS 跨域问题。

📡 封装 API 请求

api/review.js — my-shop-frontend
📄 review.js
1// api/review.js — 评价相关接口
2import request from '@/utils/request'
3
4/**
5 * 提交评价
6 * POST /api/v1/reviews
7 */
8export function submitReview(data) {
9 return request.post('/api/v1/reviews', data)
10}
11
12/**
13 * 获取商品评价列表
14 * GET /api/v1/reviews/products/:productId
15 */
16export function getProductReviews(productId, params) {
17 return request.get(
18 `/api/v1/reviews/products/${productId}`,
19 { params }
20 )
21}

✅ 接口调用成功(先发请求看看)

Elements Console Sources Network Performance
🔍 Filter All   Fetch/XHR   JS   CSS   Img
Name
Status
Type
Size
Time
reviews/products/5001?page=1&size=10
200
xhr
1.2 KB
86 ms
products/5001
200
xhr
3.4 KB
120 ms

📄 接口返回数据

{ "code": 0, "data": { "total": 128, "list": [ { "id": 1001, "userId": 20045, "nickname": "小明同学", "avatar": "https://cdn.example.com/avatar/20045.jpg", "rating": 5, "content": "音质很棒,降噪效果超好,续航也很给力。通勤必备!", "createTime": 1710460800000 }, { "id": 1000, "userId": 20089, "nickname": "花花世界", "avatar": "https://cdn.example.com/avatar/20089.jpg", "rating": 4, "content": "佩戴舒适度不错,就是价格略贵。", "createTime": 1710374400000 } ] } }

❌ 遇到 CORS 跨域错误!

问题 本地开发时,前端跑在 localhost:5173(Vite),后端跑在 localhost:8080(Spring Boot)。浏览器发现请求的域名/端口不一样,触发了 CORS 安全限制。
Elements Console Sources Network
Access to XMLHttpRequest at 'http://localhost:8080/api/v1/reviews'
from origin 'http://localhost:5173' has been blocked by CORS policy:
Response to preflight request doesn't pass access control check:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
i xhr.js:178 POST http://localhost:8080/api/v1/reviews
CORS 跨域了!开发环境下前端 5173 端口,后端 8080 端口,需要配代理。在 Vite 配置里加 proxy,让前端的请求转发到后端。

🔧 修复:配置 Vite 代理

vite.config.ts — my-shop-frontend
⚙️ vite.config.ts
1import { defineConfig } from 'vite'
2import vue from '@vitejs/plugin-vue'
3
4export default defineConfig({
5 plugins: [vue()],
6 server: {
7 proxy: {
8 '/api': {
9 target: 'http://localhost:8080',
10 changeOrigin: true
11 }
12 }
13 }
14})
💡 代理原理:前端请求 /api/xxx,Vite 开发服务器拦截这个请求,转发到 http://localhost:8080/api/xxx。这样浏览器以为是同源请求,不会触发 CORS 限制。这就是开发环境解决跨域的标准做法。
🔀 CORS 代理流程图
🌐
浏览器
localhost:5173
同源 ✅
Vite Dev Server
proxy 转发
跨域转发
🖥️
Spring Boot
localhost:8080
浏览器请求 /api/reviews → 同源(同端口 5173)
Vite 拦截 /api 前缀,转发到 localhost:8080
后端处理请求,返回数据 → 浏览器无 CORS 报错

✅ 修复后:接口正常

Elements Console Sources Network
Name
Status
Type
Size
Time
reviews/products/5001?page=1&size=10
200
xhr
1.2 KB
52 ms
reviews/products/5001?page=2&size=10
200
xhr
1.1 KB
48 ms
CORS 搞定了,数据拿到了。12:00 吃饭,下午继续。

13:30 样式对不齐 — CSS Bug Fixing

场景 吃完午饭回来,设计师在飞书群里反馈:评价列表的星星评分位置偏了,和设计稿不一样。小李用 Chrome DevTools 检查元素,找出问题。
💬 飞书私聊 — 小美(设计师)
—— 13:15 ——
小美(设计师)
小李,评价列表的星星评分位置偏了,和设计稿不一样。你看一下对比图。
小李(前端开发)
我看看

🔍 Chrome DevTools — 检查元素

Elements Console Sources Network
<div class="review-card">
<div class="reviewer">
<img class="avatar" src="..." />
<span class="nickname">小明同学</span>
<span class="date">2026-03-15</span>
</div>
<div class="star-rating"> ← 选中元素
<span class="star active"></span>
<span class="star active"></span>
...
</div>
<div class="content">音质很棒...</div>
</div>
Computed Styles — .star-rating
display: inline-flex
gap: 2px ← 问题在这!设计稿是 4px
margin-left: 0px
padding: 0px
Box Model
margin: 0
border: 0
padding: 0
120 × 20
找到了!gap 是 2px,设计稿标注是 4px。而且整体偏左了,需要加个 margin-left 微调。

🔧 修复样式

diff --git a/src/components/StarRating.vue
index a1b2c3d..e4f5g6h 100644
- .star-rating { display: inline-flex; gap: 2px; }
+ .star-rating { display: inline-flex; gap: 4px; margin-left: -2px; }

✅ 修复后效果

🔒 http://localhost:5173/product/5001/reviews
全部评价 (128)
小明同学 2026-03-15
★★★★★
音质很棒,降噪效果超好,续航也很给力。通勤必备!
花花世界 2026-03-14
★★★★
佩戴舒适度不错,就是价格略贵。
大海无量 2026-03-12
★★★★★
性价比超高,推荐入手!
样式修好了,截图给设计师确认。

14:30 QA 提 Bug — 评价提交后列表不刷新

场景 QA 王姐测到了一个 Bug:提交评价后,虽然接口返回成功了,但列表没有自动刷新,看不到新提交的评价。小李打开 Jira 看工单。
BUG-1234 评价提交后列表不刷新
🔴 High
报告人
王姐 (QA)
指派给
小李 (前端)
优先级
High
状态
🔧 处理中
复现步骤
  1. 进入商品详情页
  2. 点击"写评价"
  3. 填写评分和内容,点击提交
  4. 评价提交成功(接口 200),但列表没有显示新评价
期望结果
提交成功后,评价列表自动刷新,新评价出现在列表顶部。
实际结果
列表不刷新,需要手动刷新页面才能看到新评价。
问题很清楚:提交评价后没有刷新列表。ReviewList 组件已经有 refresh 方法了(通过 defineExpose 暴露),但父组件 ReviewPage 的 handleSubmit 没有调用它。

🔧 修复代码

ReviewPage.vue — 修复 Bug
📄 ReviewPage.vue
1<template>
2 <div class="review-page">
3 <h2>商品评价</h2>
4 <ReviewForm
5 :productId="productId"
6 @submit="handleSubmit"
7 />
8 <!-- 添加 ref -->
9 <ReviewList ref="reviewListRef" :productId="productId" />
10 </div>
11</template>
12
13<script setup>
14import { ref } from 'vue'
15import { useRoute } from 'vue-router'
16import { submitReview } from '@/api/review'
17import ReviewForm from '@/components/ReviewForm.vue'
18import ReviewList from '@/components/ReviewList.vue'
19
20const route = useRoute()
21const productId = ref(route.params.id)
22const reviewListRef = ref(null)
23
24const handleSubmit = async (formData) => {
25 await submitReview(formData)
26 message.success('评价成功')
27 // 刷新评价列表 ← 关键修复
28 reviewListRef.value.refresh()
29}
30</script>
diff --git a/src/views/product/ReviewPage.vue
@@ -6,7 +6,7 @@
- <ReviewList :productId="productId" />
+ <ReviewList ref="reviewListRef" :productId="productId" />
@@ -22,6 +22,8 @@
const productId = ref(route.params.id)
+ const reviewListRef = ref(null)
const handleSubmit = async (formData) => {
await submitReview(formData)
message.success('评价成功')
+ // 刷新评价列表
+ reviewListRef.value.refresh()
}
Bug 修好了!加了两行代码:1) 给 ReviewList 加 ref 2) 提交后调用 refresh()。

15:30 又一个 Bug:移动端适配

场景 QA 在手机上测试,发现评价卡片在小屏幕上溢出了:文字太小、间距太紧。小李用浏览器的设备模拟器复现问题。

📱 问题:小屏幕下布局溢出

🔒 iPhone SE — 375×667
商品评价
小明同学
★★★★★
音质很棒,降噪效果超好,续航也很给力。通勤必备!但是这个耳机的包装盒有点大,不太好携带出门出差的话。
2026-03-15
花花世界花花世界
★★★★☆
佩戴舒适度不错,就是价格略贵,建议做活动的时候入手更划算一些
2026-03-14
⚠️ 文字溢出、间距过紧

🔧 修复:添加媒体查询

diff --git a/src/views/product/ReviewPage.vue (style)
+ @media (max-width: 375px) {
+ .review-card {
+ padding: 12px;
+ .nickname {
+ font-size: 13px;
+ max-width: 120px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ }
+ .content {
+ font-size: 12px;
+ line-height: 1.5;
+ }
+ }
+ }
💡 媒体查询@media (max-width: 375px) 意思是"当屏幕宽度小于等于 375px 时,应用这些样式"。这是前端做响应式设计的基本方法。常见断点:375px(小手机)、768px(平板)、1024px(小笔记本)。

✅ 修复后效果

🔒 iPhone SE — 375×667
商品评价
小明同学
★★★★★
音质很棒,降噪效果超好,续航也很给力。通勤必备!
2026-03-15
花花世界
★★★★
佩戴舒适度不错,就是价格略贵。
2026-03-14
✓ 适配正常
移动端适配搞定。Chrome DevTools 的设备模拟器很好用,按 F12 切换手机模式。

16:00 提交代码 + Code Review

场景 功能做完了,Bug 也修了。小李把代码提交到 feature 分支,然后在 GitLab 上发起 Merge Request。技术负责人老陈做 Code Review。

💻 Git 提交

Terminal — zsh
~/my-shop-frontend $ git status
On branch feature/review-frontend
Changes not staged for commit:
modified: src/views/product/ReviewPage.vue
modified: vite.config.ts
Untracked files:
src/api/review.js
src/components/ReviewForm.vue
src/components/ReviewList.vue
src/components/StarRating.vue
~/my-shop-frontend $ git add .
~/my-shop-frontend $ git commit -m "feat: 商品评价页面 - 评价表单/列表/星级评分组件"
[feature/review-frontend 3a7f2d1] feat: 商品评价页面 - 评价表单/列表/星级评分组件
6 files changed, 248 insertions(+)
create mode 100644 src/api/review.js
create mode 100644 src/components/ReviewForm.vue
create mode 100644 src/components/ReviewList.vue
create mode 100644 src/components/StarRating.vue
~/my-shop-frontend $ git push origin feature/review-frontend
Enumerating objects: 12, done.
Counting objects: 100% (12/12), done.
Delta compression using up to 8 threads
Compressing objects: 100% (7/7), done.
Writing objects: 100% (8/8), 3.24 KiB | 3.24 MiB/s, done.
To gitlab.example.com:team/my-shop-frontend.git
* [new branch] feature/review-frontend -> feature/review-frontend

💬 Code Review 反馈

💬 GitLab MR #47 — 商品评价页面
—— 16:15 Code Review ——
老陈(技术负责人) 👁️ Reviewer
看了代码,整体结构不错。提几个建议:

1. ReviewList 的分页现在是点击翻页,建议用 IntersectionObserver 做滚动加载(无限滚动),用户体验更好

2. StarRating 组件可以加个 disabled prop,在列表展示时不可点击

3. API 请求的 loading 状态要处理好,防止重复提交
小李(前端开发)
好的,我改一下。分页改成滚动加载,我研究下 IntersectionObserver。
—— 16:25 修改完成 ——
小李(前端开发)
改好了,又推了一个 commit:
- 分页改为 IntersectionObserver 滚动加载
- StarRating 加了 disabled prop
- 提交按钮加了防重复点击
老陈(技术负责人)
👍 LGTM,可以合并了。

📝 滚动加载核心代码

// ReviewList.vue — 滚动加载逻辑 const observer = new IntersectionObserver((entries) => { if (entries[0].isIntersecting && hasMore.value) { loadMore() } }) // 监听底部哨兵元素 const sentinelRef = ref(null) onMounted(() => { observer.observe(sentinelRef.value) })

16:30 打包部署 — Build & Deploy

场景 MR 合并到 main 后,小李在本地打包,把 dist 目录部署到开发服务器上。团队用的是手动部署到开发环境的流程(生产环境有 CI/CD)。

📦 npm run build

Terminal — zsh
~/my-shop-frontend $ npm run build
vite v5.2.0 building for production...
transforming...
✓ 42 modules transformed.
rendering chunks...
dist/index.html 0.46 kB │ gzip: 0.30 kB
dist/assets/index-Dk4eDrFS.css 8.62 kB │ gzip: 3.21 kB
dist/assets/index-CfG8zB9R.js 42.18 kB │ gzip: 15.66 kB
dist/assets/vendor-Ab2cD3eF.js 138.45 kB │ gzip: 45.22 kB
✓ built in 2.31s
~/my-shop-frontend $ ls -la dist/
total 8
drwxr-xr-x 5 li staff 160 Mar 18 16:32 .
drwxr-xr-x 8 li staff 256 Mar 18 16:32 ..
-rw-r--r-- 1 li staff 466 Mar 18 16:32 index.html
drwxr-xr-x 4 li staff 128 Mar 18 16:32 assets/
~/my-shop-frontend $ scp -r dist/* dev@192.168.1.100:/opt/myshop/frontend/
index.html 100% 466 12.3KB/s 00:00
index-Dk4eDrFS.css 100% 8827 86.4KB/s 00:00
index-CfG8zB9R.js 100% 43.2K 312.1KB/s 00:00
vendor-Ab2cD3eF.js 100% 141.7K 1024.0KB/s 00:00
✓ 部署完成!开发环境: http://192.168.1.100

📊 打包产物分析

文件原始大小Gzip 后说明
index.html0.46 KB0.30 KB入口页面
index-*.css8.62 KB3.21 KB业务样式
index-*.js42.18 KB15.66 KB业务代码
vendor-*.js138.45 KB45.22 KB第三方库 (Vue, Router...)
合计189.71 KB64.39 KB
💡 打包原理:Vite 打包时,会做三件事:
1. Tree Shaking — 删掉没用的代码
2. Code Splitting — 把第三方库(vendor)和业务代码分开,方便缓存
3. 压缩 — 压缩 JS/CSS/HTML,文件名加 hash(如 CfG8zB9R),用于缓存控制

17:00 和后端联调 — Integration

场景 部署到开发环境后,小李和后端小张一起做联调测试。发现接口返回的时间格式不一致:后端返回的是时间戳(毫秒),前端需要的是格式化的字符串。
💬 飞书私聊 — 小张(后端开发)
—— 17:02 ——
小张(后端开发)
小李,评价接口我改了排序规则,你试试看。
小李(前端开发)
OK。另外有个问题:评价接口返回的 createTime 是时间戳(1710460800000),能改成字符串吗?比如 "2026-03-15 10:00:00" 这种。
小张(后端开发)
我看看... 我在接口上加个格式化,你等我几分钟。
—— 17:12 ——
小张(后端开发)
改好了,你试试。
小李(前端开发)
我看看...

🔍 DevTools 验证接口返回

Headers Preview Response Timing
Response — GET /api/v1/reviews/products/5001?page=1&size=10
{
"code": 0,
"data": {
"total": 128,
"list": [
{
"id": 1001,
"nickname": "小明同学",
"rating": 5,
"content": "音质很棒...",
"createTime": "2026-03-15 10:00:00" ✓ 格式化了!
},
{
"id": 1000,
"createTime": "2026-03-14 16:23:45"
}
]
}
}
💬 飞书私聊 — 小张(后端开发)
—— 17:15 ——
小李(前端开发)
OK了 ✓ 时间格式没问题了,页面上显示正常。
小张(后端开发)
👍

📋 联调常见问题清单

问题类型具体表现解决方式
数据格式不一致时间戳 vs 字符串沟通让后端改 / 前端自己格式化
字段名不一致后端 create_time vs 前端 createTime统一命名规范
空值处理后端返回 null,前端报错前端做空值保护 data ?? ''
CORS 跨域开发环境跨域请求被拦截配置 Vite proxy
分页参数page 从 0 还是 1 开始?和后端约定好

17:30 下班总结 — Day Summary

场景 一天的工作结束了。小李关掉电脑前,回顾今天做了什么。

🕐 前端一天的工作节奏

09:00–09:20 早站会 + 拿设计稿

看设计稿,理解 UI 需求,提取标注(间距、颜色、字体)。

耗时约 20 分钟

09:40–10:30 搭组件 + 写页面

创建 ReviewPage、ReviewForm、ReviewList、StarRating 四个组件,完成页面结构和交互逻辑。

耗时约 2 小时

10:30–12:00 写样式 + 调接口 + 处理跨域

对照设计稿写 CSS/SCSS。调后端接口时遇到 CORS 跨域,配置 Vite proxy 解决。

耗时约 1.5 小时

13:30–14:30 修样式 Bug + 适配

设计师反馈星星间距不对,用 DevTools 排查并修复。移动端适配加媒体查询。

耗时约 1 小时

14:30–15:30 修 QA 的 Bug

评价提交后列表不刷新 — 给 ReviewList 加 ref,提交后调用 refresh()。

耗时约 1 小时

16:00–16:30 Code Review + 修改

老陈建议用 IntersectionObserver 做滚动加载,改完再提交。

耗时约 30 分钟

16:30–17:00 打包部署

npm run build,scp 到开发服务器。

耗时约 30 分钟

17:00–17:30 和后端联调

测试接口联调,发现时间格式不一致,沟通后端改好,验证通过。

耗时约 30 分钟

🎯 前端工作特点

特点说明
和设计稿对齐是日常 间距、颜色、字体,每个像素都要对照。Chrome DevTools 是最好的工具。
DevTools 是最常用的工具 Network 看请求、Elements 看样式、Console 看报错。前端调试 80% 靠它。
跨域问题经常遇到 开发环境前后端不同端口,需要配代理(Vite proxy / webpack proxy)。
移动端适配是额外负担 PC 看着好好的,手机上可能就溢出了。媒体查询是基本功。
和后端联调最常见 数据格式不一致、字段名不统一、空值处理——沟通是关键。
组件化思维 把页面拆成独立的组件,好维护、好复用、好测试。

🛠️ 今天用到的工具

工具用途使用频率
VS Code写代码、改样式、看文件⭐⭐⭐⭐⭐ 全天
Chrome DevTools看请求、查样式、调 Bug⭐⭐⭐⭐⭐ 全天
TerminalGit 操作、打包部署⭐⭐⭐ 零散使用
Figma看设计稿、量间距⭐⭐ 早上用一次
飞书站会、沟通、Code Review⭐⭐⭐ 零散使用
GitLabMerge Request、Code Review⭐⭐ 下午用
Jira看 Bug 工单⭐ 下午用一次

📊 今日代码统计

6
新增文件
248
新增代码行
2
修复 Bug
3
Git Commits
189 KB
打包产物

🔄 今天从零到一的成果

早上 09:00 — 什么都没有
📋
空白项目
下午 17:30 — 功能上线
无线蓝牙耳机 Pro Max
★★★★★ 4.8
128 条评价
✍️ 写评价
★★★★★
音质很棒,降噪效果超好...
前端开发的一天:写代码只占 50%,另外 50% 是调 Bug、对设计稿、和后端联调、做 Code Review。
但看到用户用上自己做的页面,那一刻觉得一切都值了。明天继续加油!💪